decompiled_code:
void determine_director_sets()
{
__int64 v0; // rbx
__int64 v1; // rdi

if ( nr_of_rules > 0 )
{
v0 = 0LL;
do
{
v1 = *(_QWORD *)(all_rules + 8 * v0++);
determine_director_set(v1);
}
while ( nr_of_rules > (int)v0 );
}
}

canonical_decompiled_code:
void func8()
{
__int64 v0; // rbx
__int64 v1; // rdi

if ( nr_of_rules > 0 )
{
v0 = 0LL;
do
{
v1 = *(_QWORD *)(all_rules + 8 * v0++);
func7(v1);
}
while ( nr_of_rules > (int)v0 );
}
}

original_code:
static void determine_director_sets ()
 { int ix;
   for (ix = 0; ix < nr_of_rules; ix++)
      determine_director_set (all_rules[ix]);
 }

canonical_original_code:
static void determine_director_sets()
 { int ix;
   for (ix = 0; ix < nr_of_rules; ix++)
      determine_director_set (all_rules[ix]);
 }


repo: tjordanchat/eag

decompiled_code:
__int64 __fastcall initial_first_sets_in_member(__int64 a1, __int64 a2, __int64 a3, __int64 a4)
{
__int64 v5; // rdi
__int64 result; // rax

v5 = *(unsigned int *)(a1 + 24);
if ( (_DWORD)v5 == 2 )
return initial_first_sets_in_semi(a1);
if ( (int)v5 > 2 )
{
if ( (_DWORD)v5 == 3 )
{
*(_QWORD *)(a1 + 8) = &unk_B14;
return result;
}
goto LABEL_10;
}
if ( (_DWORD)v5 )
{
if ( (_DWORD)v5 == 1 )
return initial_first_sets_in_terminal(a1);
LABEL_10:
result = bad_tag(v5, "initial_first_sets_in_member", a3, a4, a1);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1, __int64 a2, __int64 a3, __int64 a4)
{
__int64 v5; // rdi
__int64 result; // rax

v5 = *(unsigned int *)(a1 + 24);
if ( (_DWORD)v5 == 2 )
return func5(a1);
if ( (int)v5 > 2 )
{
if ( (_DWORD)v5 == 3 )
{
*(_QWORD *)(a1 + 8) = &unk_B14;
return result;
}
goto LABEL_10;
}
if ( (_DWORD)v5 )
{
if ( (_DWORD)v5 == 1 )
return func3(a1);
LABEL_10:
result = bad_tag(v5, "initial_first_sets_in_member", a3, a4, a1);
}
return result;
}

original_code:
static void initial_first_sets_in_member (member m)
 { switch (m -> tag)
      { case 0: break;
        case 1: initial_first_sets_in_terminal (m); break;
        case 2: initial_first_sets_in_semi (m); break;
        case 3: m -> first = ""; break;
        default: bad_tag (m -> tag, "initial_first_sets_in_member");
      }
 }

canonical_original_code:
static void initial_first_sets_in_member(struct member_rec *m)
 { switch (m -> tag)
      { case 0: break;
        case 1: initial_first_sets_in_terminal (m); break;
        case 2: initial_first_sets_in_semi (m); break;
        case 3: m -> first = ""; break;
        default: bad_tag (m -> tag, "initial_first_sets_in_member");
      }
 }

variable_types: struct member_rec { int empty; int followlayout; char *first; int number; int sonnr; int tag; union { struct call_rec { char *nonterminal; struct pos_list_rec { int size; int room; struct pos_rec { int kind; struct expr_rec { int tag; union { struct affix_rec { char *name; int type; struct affix_rec *next; struct value_rec { int admin_nr; int ref_count; void *dptr; int tag; union { char *str; int inum; double rnum; struct value_list_rec { int size; int room; struct value_rec **array; } *tuple; int slat; struct int_list_rec { int size; int room; int *array; } *elat; struct value_rec *free; } u; } *val; int ref_count; int reachable; int tag; union { struct variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec { char *nonterminal; struct meta_alt_list_rec { int size; int room; struct meta_alt_rec { struct expr_rec *e; int number; } **array; } *alts; int ext; int type; int kind; int empty; int number; struct value_rec *mvalue; int reachable; struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec { int number; struct element_def_list_rec { int size; int room; struct element_def_rec **array; } *defs; } *set; } *lat_repr; int needs_rec; int needs_recbup; } *def; } var; char *str; int inum; double rnum; struct cset_rec { int kind; char *str; } *semi; struct element_rec { char *eltnm; struct element_def_rec *def; } elt; struct expr_rec *cexpr; } u; } *single; struct affix_list_rec { int size; int room; struct affix_rec **array; } *compos; struct affix_list_rec *concat; struct affix_list_rec *uni; } u; } *ex; int type; struct element_def_rec *lat_repr; } **array; } *display; struct rule_rec { char *nonterminal; struct alt_list_rec { int size; int room; struct alt_rec { struct pos_list_rec *display; struct member_list_rec { int size; int room; struct member_rec **array; } *members; int number; int nodenr; int nrsons; struct affix_rec *locals; int empty; char *first; char *director; int rule_nr; } **array; } *alts; int kind; int empty; int lex; int ext; int number; int placeholder; int startswithlayout; int endsinlayout; char *first; char *follow; struct pos_list_rec *proto_display; int reachable; int has_sons; int goal; struct lextree_rec { char *remainder; struct lexend_list_rec { int size; int room; struct lexend_rec { int nodenr; struct int_list_rec *valuenrs; } **array; } *prods; struct lextree_list_rec { int size; int room; struct lextree_rec **array; } *tails; } *rev_tree; } *def; } call; char *terminal; struct semiterminal_rec { struct cset_rec *set; struct pos_list_rec *display; } semi; } u; } *

return_type: void

user_defined_types: struct member_rec { int empty; int followlayout; char *first; int number; int sonnr; int tag; union { struct call_rec call; char *terminal; struct semiterminal_rec semi; } u; }

user_defined_types: struct call_rec { char *nonterminal; struct pos_list_rec *display; struct rule_rec *def; }

user_defined_types: struct pos_list_rec { int size; int room; struct pos_rec **array; }

user_defined_types: struct rule_rec { char *nonterminal; struct alt_list_rec *alts; int kind; int empty; int lex; int ext; int number; int placeholder; int startswithlayout; int endsinlayout; char *first; char *follow; struct pos_list_rec *proto_display; int reachable; int has_sons; int goal; struct lextree_rec *rev_tree; }

user_defined_types: struct alt_list_rec { int size; int room; struct alt_rec **array; }

user_defined_types: struct lextree_rec { char *remainder; struct lexend_list_rec *prods; struct lextree_list_rec *tails; }

user_defined_types: struct pos_rec { int kind; struct expr_rec *ex; int type; struct element_def_rec *lat_repr; }

user_defined_types: struct lexend_list_rec { int size; int room; struct lexend_rec **array; }

user_defined_types: struct expr_rec { int tag; union { struct affix_rec *single; struct affix_list_rec *compos; struct affix_list_rec *concat; struct affix_list_rec *uni; } u; }

user_defined_types: struct alt_rec { struct pos_list_rec *display; struct member_list_rec *members; int number; int nodenr; int nrsons; struct affix_rec *locals; int empty; char *first; char *director; int rule_nr; }

user_defined_types: struct affix_rec { char *name; int type; struct affix_rec *next; struct value_rec *val; int ref_count; int reachable; int tag; union { struct variable_rec var; char *str; int inum; double rnum; struct cset_rec *semi; struct element_rec elt; struct expr_rec *cexpr; } u; }

user_defined_types: struct value_rec { int admin_nr; int ref_count; void *dptr; int tag; union { char *str; int inum; double rnum; struct value_list_rec *tuple; int slat; struct int_list_rec *elat; struct value_rec *free; } u; }

user_defined_types: struct variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec *def; }

user_defined_types: struct meta_rule_rec { char *nonterminal; struct meta_alt_list_rec *alts; int ext; int type; int kind; int empty; int number; struct value_rec *mvalue; int reachable; struct element_def_rec *lat_repr; int needs_rec; int needs_recbup; }

user_defined_types: struct meta_alt_list_rec { int size; int room; struct meta_alt_rec **array; }

user_defined_types: struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec *set; }

user_defined_types: struct element_set_rec { int number; struct element_def_list_rec *defs; }


decompiled_code:
__int64 __fastcall initial_first_sets_in_members(unsigned int *a1, __int64 a2, __int64 a3, __int64 a4)
{
__int64 result; // rax
__int64 v6; // rbx
__int64 v7; // rdi

if ( a1 )
{
result = *a1;
if ( (int)result > 0 )
{
v6 = 0LL;
do
{
v7 = *(_QWORD *)(*((_QWORD *)a1 + 1) + 8 * v6++);
result = initial_first_sets_in_member(v7, a2, a3, a4);
}
while ( (int)*a1 > (int)v6 );
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(unsigned int *a1, __int64 a2, __int64 a3, __int64 a4)
{
__int64 result; // rax
__int64 v6; // rbx
__int64 v7; // rdi

if ( a1 )
{
result = *a1;
if ( (int)result > 0 )
{
v6 = 0LL;
do
{
v7 = *(_QWORD *)(*((_QWORD *)a1 + 1) + 8 * v6++);
result = func9(v7, a2, a3, a4);
}
while ( (int)*a1 > (int)v6 );
}
}
return result;
}

original_code:
static void initial_first_sets_in_members (member_list mems)
 { int ix;
   if (mems == ((member_list) ((void *)0))) return;
   for (ix = 0; ix < mems -> size; ix++)
      initial_first_sets_in_member (mems -> array[ix]);
 }

canonical_original_code:
static void initial_first_sets_in_members(struct member_list_rec *mems)
 { int ix;
   if (mems == ((member_list) ((void *)0))) return;
   for (ix = 0; ix < mems -> size; ix++)
      initial_first_sets_in_member (mems -> array[ix]);
 }

variable_types: struct member_list_rec { int size; int room; struct member_rec { int empty; int followlayout; char *first; int number; int sonnr; int tag; union { struct call_rec { char *nonterminal; struct pos_list_rec { int size; int room; struct pos_rec { int kind; struct expr_rec { int tag; union { struct affix_rec { char *name; int type; struct affix_rec *next; struct value_rec { int admin_nr; int ref_count; void *dptr; int tag; union { char *str; int inum; double rnum; struct value_list_rec { int size; int room; struct value_rec **array; } *tuple; int slat; struct int_list_rec { int size; int room; int *array; } *elat; struct value_rec *free; } u; } *val; int ref_count; int reachable; int tag; union { struct variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec { char *nonterminal; struct meta_alt_list_rec { int size; int room; struct meta_alt_rec { struct expr_rec *e; int number; } **array; } *alts; int ext; int type; int kind; int empty; int number; struct value_rec *mvalue; int reachable; struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec { int number; struct element_def_list_rec { int size; int room; struct element_def_rec **array; } *defs; } *set; } *lat_repr; int needs_rec; int needs_recbup; } *def; } var; char *str; int inum; double rnum; struct cset_rec { int kind; char *str; } *semi; struct element_rec { char *eltnm; struct element_def_rec *def; } elt; struct expr_rec *cexpr; } u; } *single; struct affix_list_rec { int size; int room; struct affix_rec **array; } *compos; struct affix_list_rec *concat; struct affix_list_rec *uni; } u; } *ex; int type; struct element_def_rec *lat_repr; } **array; } *display; struct rule_rec { char *nonterminal; struct alt_list_rec { int size; int room; struct alt_rec { struct pos_list_rec *display; struct member_list_rec *members; int number; int nodenr; int nrsons; struct affix_rec *locals; int empty; char *first; char *director; int rule_nr; } **array; } *alts; int kind; int empty; int lex; int ext; int number; int placeholder; int startswithlayout; int endsinlayout; char *first; char *follow; struct pos_list_rec *proto_display; int reachable; int has_sons; int goal; struct lextree_rec { char *remainder; struct lexend_list_rec { int size; int room; struct lexend_rec { int nodenr; struct int_list_rec *valuenrs; } **array; } *prods; struct lextree_list_rec { int size; int room; struct lextree_rec **array; } *tails; } *rev_tree; } *def; } call; char *terminal; struct semiterminal_rec { struct cset_rec *set; struct pos_list_rec *display; } semi; } u; } **array; } *

variable_types: ix int

user_defined_types: struct member_list_rec { int size; int room; struct member_rec **array; }

user_defined_types: struct member_rec { int empty; int followlayout; char *first; int number; int sonnr; int tag; union { struct call_rec call; char *terminal; struct semiterminal_rec semi; } u; }


decompiled_code:
__int64 __fastcall initial_first_sets_in_alts(unsigned int *a1, __int64 a2, __int64 a3, __int64 a4)
{
__int64 result; // rax
__int64 v5; // rbx
__int64 v6; // rax

result = *a1;
if ( (int)result > 0 )
{
v5 = 0LL;
do
{
v6 = *(_QWORD *)(*((_QWORD *)a1 + 1) + 8 * v5++);
result = initial_first_sets_in_members(*(unsigned int **)(v6 + 8), a2, a3, a4);
}
while ( (int)*a1 > (int)v5 );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func11(unsigned int *a1, __int64 a2, __int64 a3, __int64 a4)
{
__int64 result; // rax
__int64 v5; // rbx
__int64 v6; // rax

result = *a1;
if ( (int)result > 0 )
{
v5 = 0LL;
do
{
v6 = *(_QWORD *)(*((_QWORD *)a1 + 1) + 8 * v5++);
result = func10(*(unsigned int **)(v6 + 8), a2, a3, a4);
}
while ( (int)*a1 > (int)v5 );
}
return result;
}

original_code:
static void initial_first_sets_in_alts (alt_list alts)
 { int ix;
   for (ix = 0; ix < alts -> size; ix++)
      initial_first_sets_in_members (alts -> array[ix] -> members);
 }

canonical_original_code:
static void initial_first_sets_in_alts(struct alt_list_rec *alts)
 { int ix;
   for (ix = 0; ix < alts -> size; ix++)
      initial_first_sets_in_members (alts -> array[ix] -> members);
 }

variable_types: struct alt_list_rec { int size; int room; struct alt_rec { struct pos_list_rec { int size; int room; struct pos_rec { int kind; struct expr_rec { int tag; union { struct affix_rec { char *name; int type; struct affix_rec *next; struct value_rec { int admin_nr; int ref_count; void *dptr; int tag; union { char *str; int inum; double rnum; struct value_list_rec { int size; int room; struct value_rec **array; } *tuple; int slat; struct int_list_rec { int size; int room; int *array; } *elat; struct value_rec *free; } u; } *val; int ref_count; int reachable; int tag; union { struct variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec { char *nonterminal; struct meta_alt_list_rec { int size; int room; struct meta_alt_rec { struct expr_rec *e; int number; } **array; } *alts; int ext; int type; int kind; int empty; int number; struct value_rec *mvalue; int reachable; struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec { int number; struct element_def_list_rec { int size; int room; struct element_def_rec **array; } *defs; } *set; } *lat_repr; int needs_rec; int needs_recbup; } *def; } var; char *str; int inum; double rnum; struct cset_rec { int kind; char *str; } *semi; struct element_rec { char *eltnm; struct element_def_rec *def; } elt; struct expr_rec *cexpr; } u; } *single; struct affix_list_rec { int size; int room; struct affix_rec **array; } *compos; struct affix_list_rec *concat; struct affix_list_rec *uni; } u; } *ex; int type; struct element_def_rec *lat_repr; } **array; } *display; struct member_list_rec { int size; int room; struct member_rec { int empty; int followlayout; char *first; int number; int sonnr; int tag; union { struct call_rec { char *nonterminal; struct pos_list_rec *display; struct rule_rec { char *nonterminal; struct alt_list_rec *alts; int kind; int empty; int lex; int ext; int number; int placeholder; int startswithlayout; int endsinlayout; char *first; char *follow; struct pos_list_rec *proto_display; int reachable; int has_sons; int goal; struct lextree_rec { char *remainder; struct lexend_list_rec { int size; int room; struct lexend_rec { int nodenr; struct int_list_rec *valuenrs; } **array; } *prods; struct lextree_list_rec { int size; int room; struct lextree_rec **array; } *tails; } *rev_tree; } *def; } call; char *terminal; struct semiterminal_rec { struct cset_rec *set; struct pos_list_rec *display; } semi; } u; } **array; } *members; int number; int nodenr; int nrsons; struct affix_rec *locals; int empty; char *first; char *director; int rule_nr; } **array; } *

user_defined_types: struct pos_list_rec { int size; int room; struct pos_rec **array; }

user_defined_types: struct call_rec { char *nonterminal; struct pos_list_rec *display; struct rule_rec *def; }


decompiled_code:
void __fastcall initial_first_sets_in_rule(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v3; // rcx
__int16 v4[5]; // [rsp+1h] [rbp-Bh] BYREF

v3 = *(unsigned int *)(a1 + 28);
if ( !(_DWORD)v3 && (*(_BYTE *)(a1 + 16) & 6) == 0 )
{
initial_first_sets_in_alts(*(unsigned int **)(a1 + 8), a2, a3, v3);
if ( *(_DWORD *)(a1 + 36) )
{
v4[0] = 60;
*(_QWORD *)(a1 + 48) = addto_names(v4);
}
}
}

original_code:
static void initial_first_sets_in_rule (rule srule)
 { char buf[3];
   if (srule -> ext) return;
   if (srule -> kind & 2) return;
   if (srule -> kind & 4) return;
   initial_first_sets_in_alts (srule -> alts);
   if (!srule -> placeholder) return;
   buf[0] = "<|>"[0];
   if ("<|"[0] != "<|>"[0])
      { buf[1] = "<|"[0];
        buf[2] = '\0';
      }
   else buf[1] = '\0';
   srule -> first = addto_names (buf);
 }

canonical_original_code:
static void initial_first_sets_in_rule(struct rule_rec *srule)
 { char buf[3];
   if (srule -> ext) return;
   if (srule -> kind & 2) return;
   if (srule -> kind & 4) return;
   initial_first_sets_in_alts (srule -> alts);
   if (!srule -> placeholder) return;
   buf[0] = "<|>"[0];
   if ("<|"[0] != "<|>"[0])
      { buf[1] = "<|"[0];
        buf[2] = '\0';
      }
   else buf[1] = '\0';
   srule -> first = addto_names (buf);
 }

variable_types: struct rule_rec { char *nonterminal; struct alt_list_rec { int size; int room; struct alt_rec { struct pos_list_rec { int size; int room; struct pos_rec { int kind; struct expr_rec { int tag; union { struct affix_rec { char *name; int type; struct affix_rec *next; struct value_rec { int admin_nr; int ref_count; void *dptr; int tag; union { char *str; int inum; double rnum; struct value_list_rec { int size; int room; struct value_rec **array; } *tuple; int slat; struct int_list_rec { int size; int room; int *array; } *elat; struct value_rec *free; } u; } *val; int ref_count; int reachable; int tag; union { struct variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec { char *nonterminal; struct meta_alt_list_rec { int size; int room; struct meta_alt_rec { struct expr_rec *e; int number; } **array; } *alts; int ext; int type; int kind; int empty; int number; struct value_rec *mvalue; int reachable; struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec { int number; struct element_def_list_rec { int size; int room; struct element_def_rec **array; } *defs; } *set; } *lat_repr; int needs_rec; int needs_recbup; } *def; } var; char *str; int inum; double rnum; struct cset_rec { int kind; char *str; } *semi; struct element_rec { char *eltnm; struct element_def_rec *def; } elt; struct expr_rec *cexpr; } u; } *single; struct affix_list_rec { int size; int room; struct affix_rec **array; } *compos; struct affix_list_rec *concat; struct affix_list_rec *uni; } u; } *ex; int type; struct element_def_rec *lat_repr; } **array; } *display; struct member_list_rec { int size; int room; struct member_rec { int empty; int followlayout; char *first; int number; int sonnr; int tag; union { struct call_rec { char *nonterminal; struct pos_list_rec *display; struct rule_rec *def; } call; char *terminal; struct semiterminal_rec { struct cset_rec *set; struct pos_list_rec *display; } semi; } u; } **array; } *members; int number; int nodenr; int nrsons; struct affix_rec *locals; int empty; char *first; char *director; int rule_nr; } **array; } *alts; int kind; int empty; int lex; int ext; int number; int placeholder; int startswithlayout; int endsinlayout; char *first; char *follow; struct pos_list_rec *proto_display; int reachable; int has_sons; int goal; struct lextree_rec { char *remainder; struct lexend_list_rec { int size; int room; struct lexend_rec { int nodenr; struct int_list_rec *valuenrs; } **array; } *prods; struct lextree_list_rec { int size; int room; struct lextree_rec **array; } *tails; } *rev_tree; } *

variable_types:
buf
char [3]

user_defined_types: struct rule_rec { char *nonterminal; struct alt_list_rec *alts; int kind; int empty; int lex; int ext; int number; int placeholder; int startswithlayout; int endsinlayout; char *first; char *follow; struct pos_list_rec *proto_display; int reachable; int has_sons; int goal; struct lextree_rec *rev_tree; }

user_defined_types: struct alt_list_rec { int size; int room; struct alt_rec **array; }


decompiled_code:
void __fastcall initial_first_sets_in_rules(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v3; // rbx
__int64 v4; // rdi

if ( nr_of_rules > 0 )
{
v3 = 0LL;
do
{
v4 = *(_QWORD *)(all_rules + 8 * v3++);
initial_first_sets_in_rule(v4, a2, a3);
}
while ( nr_of_rules > (int)v3 );
}
}

canonical_decompiled_code:
void __fastcall func13(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v3; // rbx
__int64 v4; // rdi

if ( nr_of_rules > 0 )
{
v3 = 0LL;
do
{
v4 = *(_QWORD *)(all_rules + 8 * v3++);
func12(v4, a2, a3);
}
while ( nr_of_rules > (int)v3 );
}
}

original_code:
static void initial_first_sets_in_rules ()
 { int ix;
   for (ix = 0; ix < nr_of_rules; ix++)
      initial_first_sets_in_rule (all_rules[ix]);
 }

canonical_original_code:
static void initial_first_sets_in_rules()
 { int ix;
   for (ix = 0; ix < nr_of_rules; ix++)
      initial_first_sets_in_rule (all_rules[ix]);
 }


decompiled_code:
__int64 __fastcall add_first_of_member_to_follow_set(__int64 a1, unsigned __int8 *a2, __int64 a3, __int64 a4)
{
__int64 v4; // r8
__int64 result; // rax

v4 = *(unsigned int *)(a1 + 24);
if ( (int)v4 <= 2 )
{
if ( (int)v4 > 0 )
return addto_set(a2, *(unsigned __int8 **)(a1 + 8));
if ( !(_DWORD)v4 )
return addto_set(a2, *(unsigned __int8 **)(*(_QWORD *)(a1 + 48) + 48LL));
return bad_tag((unsigned int)v4, "add_first_of_member_to_follow_set", a3, a4, v4);
}
if ( (_DWORD)v4 != 3 )
return bad_tag((unsigned int)v4, "add_first_of_member_to_follow_set", a3, a4, v4);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func14(__int64 a1, unsigned __int8 *a2, __int64 a3, __int64 a4)
{
__int64 v4; // r8
__int64 result; // rax

v4 = *(unsigned int *)(a1 + 24);
if ( (int)v4 <= 2 )
{
if ( (int)v4 > 0 )
return func2(a2, *(unsigned __int8 **)(a1 + 8));
if ( !(_DWORD)v4 )
return func2(a2, *(unsigned __int8 **)(*(_QWORD *)(a1 + 48) + 48LL));
return bad_tag((unsigned int)v4, "add_first_of_member_to_follow_set", a3, a4, v4);
}
if ( (_DWORD)v4 != 3 )
return bad_tag((unsigned int)v4, "add_first_of_member_to_follow_set", a3, a4, v4);
return result;
}

original_code:
static void add_first_of_member_to_follow_set (member m, char *s)
 { switch (m -> tag)
      { case 0:
    addto_set (s, m -> u.call.def -> first); break;
        case 1:
        case 2: addto_set (s, m -> first);
        case 3: break;
        default: bad_tag (m -> tag, "add_first_of_member_to_follow_set");
      };
 }

canonical_original_code:
static void add_first_of_member_to_follow_set(struct member_rec *m, char *s)
 { switch (m -> tag)
      { case 0:
    addto_set (s, m -> u.call.def -> first); break;
        case 1:
        case 2: addto_set (s, m -> first);
        case 3: break;
        default: bad_tag (m -> tag, "add_first_of_member_to_follow_set");
      };
 }

variable_types:
s
char *

user_defined_types: struct semiterminal_rec { struct cset_rec *set; struct pos_list_rec *display; }

user_defined_types: struct lextree_rec { char *remainder; struct lexend_list_rec *prods; struct lextree_list_rec *tails; }

user_defined_types: struct pos_rec { int kind; struct expr_rec *ex; int type; struct element_def_rec *lat_repr; }

user_defined_types: struct lextree_list_rec { int size; int room; struct lextree_rec **array; }

user_defined_types: struct lexend_rec { int nodenr; struct int_list_rec *valuenrs; }

user_defined_types: struct affix_list_rec { int size; int room; struct affix_rec **array; }

user_defined_types: struct element_rec { char *eltnm; struct element_def_rec *def; }

user_defined_types: struct cset_rec { int kind; char *str; }

user_defined_types: struct value_list_rec { int size; int room; struct value_rec **array; }

user_defined_types: struct int_list_rec { int size; int room; int *array; }

user_defined_types: struct meta_alt_rec { struct expr_rec *e; int number; }

user_defined_types: struct element_def_list_rec { int size; int room; struct element_def_rec **array; }


decompiled_code:
void __fastcall try_update_follow_set(__int64 a1, int *a2, int a3, __int64 a4)
{
__int64 v6; // rcx
__int64 v7; // rax
unsigned __int8 v8[296]; // [rsp+0h] [rbp-128h] BYREF

v8[0] = 0;
if ( (*(_BYTE *)(a4 + 16) & 6) == 0 )
{
addto_set(v8, *(unsigned __int8 **)(a4 + 56));
add_first_of_members_to_follow_set((__int64)a2, a3, v8, v6);
try_add_rule_set_to_follow_set(a1, a2, a3, v8);
if ( strcmp(*(const char **)(a4 + 56), (const char *)v8) )
{
v7 = addto_names(v8);
change = 1;
*(_QWORD *)(a4 + 56) = v7;
}
}
}

original_code:
static void try_update_follow_set (rule srule, member_list mems,
        int from, rule target)
 { char fset[256];
   fset[0] = '\0';
   if ((target -> kind & 2) ||
       (target -> kind & 4)) return;
   addto_set (fset, target -> follow);
   add_first_of_members_to_follow_set (mems, from, fset);
   try_add_rule_set_to_follow_set (srule, mems, from, fset);
   if (strcmp (target -> follow, fset) != 0)
      { target -> follow = addto_names (fset);
        change = 1;
      };
 }

canonical_original_code:
static void try_update_follow_set(struct rule_rec *srule, struct member_list_rec *mems, int from, struct rule_rec *target)
 { char fset[256];
   fset[0] = '\0';
   if ((target -> kind & 2) ||
       (target -> kind & 4)) return;
   addto_set (fset, target -> follow);
   add_first_of_members_to_follow_set (mems, from, fset);
   try_add_rule_set_to_follow_set (srule, mems, from, fset);
   if (strcmp (target -> follow, fset) != 0)
      { target -> follow = addto_names (fset);
        change = 1;
      };
 }

variable_types:
mems
struct member_list_rec *

variable_types: from int

variable_types:
target
struct rule_rec *

variable_types:
fset
char [256]

user_defined_types: struct lexend_list_rec { int size; int room; struct lexend_rec **array; }

user_defined_types: struct alt_rec { struct pos_list_rec *display; struct member_list_rec *members; int number; int nodenr; int nrsons; struct affix_rec *locals; int empty; char *first; char *director; int rule_nr; }

user_defined_types: struct member_list_rec { int size; int room; struct member_rec **array; }

user_defined_types: struct member_rec { int empty; int followlayout; char *first; int number; int sonnr; int tag; union { struct call_rec call; char *terminal; struct semiterminal_rec semi; } u; }

user_defined_types: struct expr_rec { int tag; union { struct affix_rec *single; struct affix_list_rec *compos; struct affix_list_rec *concat; struct affix_list_rec *uni; } u; }

user_defined_types: struct affix_rec { char *name; int type; struct affix_rec *next; struct value_rec *val; int ref_count; int reachable; int tag; union { struct variable_rec var; char *str; int inum; double rnum; struct cset_rec *semi; struct element_rec elt; struct expr_rec *cexpr; } u; }

user_defined_types: struct value_rec { int admin_nr; int ref_count; void *dptr; int tag; union { char *str; int inum; double rnum; struct value_list_rec *tuple; int slat; struct int_list_rec *elat; struct value_rec *free; } u; }

user_defined_types: struct variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec *def; }

user_defined_types: struct meta_rule_rec { char *nonterminal; struct meta_alt_list_rec *alts; int ext; int type; int kind; int empty; int number; struct value_rec *mvalue; int reachable; struct element_def_rec *lat_repr; int needs_rec; int needs_recbup; }

user_defined_types: struct meta_alt_list_rec { int size; int room; struct meta_alt_rec **array; }

user_defined_types: struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec *set; }

user_defined_types: struct element_set_rec { int number; struct element_def_list_rec *defs; }


decompiled_code:
void __fastcall determine_follow_sets_in_members(__int64 a1, __int64 a2)
{
__int64 v2; // rbx
int v3; // edx
__int64 v4; // rax

if ( a2 && *(int *)a2 > 0 )
{
v2 = 0LL;
do
{
while ( 1 )
{
v3 = v2 + 1;
v4 = *(_QWORD *)(*(_QWORD *)(a2 + 8) + 8 * v2);
if ( !*(_DWORD *)(v4 + 24) )
break;
if ( *(_DWORD *)a2 <= (int)++v2 )
return;
}
++v2;
try_update_follow_set(a1, (int *)a2, v3, *(_QWORD *)(v4 + 48));
}
while ( *(_DWORD *)a2 > (int)v2 );
}
}

original_code:
static void determine_follow_sets_in_members (rule srule, member_list mems)
 { int ix;
   if (mems == ((member_list) ((void *)0))) return;
   for (ix = 0; ix < mems -> size; ix++)
      if (mems -> array[ix] -> tag == 0)
         try_update_follow_set (srule, mems, ix + 1,
   mems -> array[ix] -> u.call.def);
 }

canonical_original_code:
static void determine_follow_sets_in_members(struct rule_rec *srule, struct member_list_rec *mems)
 { int ix;
   if (mems == ((member_list) ((void *)0))) return;
   for (ix = 0; ix < mems -> size; ix++)
      if (mems -> array[ix] -> tag == 0)
         try_update_follow_set (srule, mems, ix + 1,
   mems -> array[ix] -> u.call.def);
 }

user_defined_types: struct rule_rec { char *nonterminal; struct alt_list_rec *alts; int kind; int empty; int lex; int ext; int number; int placeholder; int startswithlayout; int endsinlayout; char *first; char *follow; struct pos_list_rec *proto_display; int reachable; int has_sons; int goal; struct lextree_rec *rev_tree; }

user_defined_types: struct alt_list_rec { int size; int room; struct alt_rec **array; }

user_defined_types: struct lextree_rec { char *remainder; struct lexend_list_rec *prods; struct lextree_list_rec *tails; }

user_defined_types: struct lextree_list_rec { int size; int room; struct lextree_rec **array; }

user_defined_types: struct pos_list_rec { int size; int room; struct pos_rec **array; }

user_defined_types: struct lexend_rec { int nodenr; struct int_list_rec *valuenrs; }

user_defined_types: struct pos_rec { int kind; struct expr_rec *ex; int type; struct element_def_rec *lat_repr; }

user_defined_types: struct call_rec { char *nonterminal; struct pos_list_rec *display; struct rule_rec *def; }

user_defined_types: struct semiterminal_rec { struct cset_rec *set; struct pos_list_rec *display; }

user_defined_types: struct affix_list_rec { int size; int room; struct affix_rec **array; }

user_defined_types: struct element_rec { char *eltnm; struct element_def_rec *def; }

user_defined_types: struct cset_rec { int kind; char *str; }


decompiled_code:
void __fastcall determine_follow_sets_in_alts(__int64 a1, __int64 a2)
{
__int64 v2; // rbx
__int64 v3; // rax

if ( *(int *)a2 > 0 )
{
v2 = 0LL;
do
{
v3 = *(_QWORD *)(*(_QWORD *)(a2 + 8) + 8 * v2++);
determine_follow_sets_in_members(a1, *(_QWORD *)(v3 + 8));
}
while ( *(_DWORD *)a2 > (int)v2 );
}
}

original_code:
static void determine_follow_sets_in_alts (rule srule, alt_list alts)
 { int ix;
   for (ix = 0; ix < alts -> size; ix++)
      determine_follow_sets_in_members (srule,
            alts -> array[ix] -> members);
 }

canonical_original_code:
static void determine_follow_sets_in_alts(struct rule_rec *srule, struct alt_list_rec *alts)
 { int ix;
   for (ix = 0; ix < alts -> size; ix++)
      determine_follow_sets_in_members (srule,
            alts -> array[ix] -> members);
 }

variable_types:
alts
struct alt_list_rec *

user_defined_types: struct lexend_list_rec { int size; int room; struct lexend_rec **array; }

user_defined_types: struct alt_rec { struct pos_list_rec *display; struct member_list_rec *members; int number; int nodenr; int nrsons; struct affix_rec *locals; int empty; char *first; char *director; int rule_nr; }

user_defined_types: struct member_list_rec { int size; int room; struct member_rec **array; }

user_defined_types: struct member_rec { int empty; int followlayout; char *first; int number; int sonnr; int tag; union { struct call_rec call; char *terminal; struct semiterminal_rec semi; } u; }

user_defined_types: struct expr_rec { int tag; union { struct affix_rec *single; struct affix_list_rec *compos; struct affix_list_rec *concat; struct affix_list_rec *uni; } u; }

user_defined_types: struct affix_rec { char *name; int type; struct affix_rec *next; struct value_rec *val; int ref_count; int reachable; int tag; union { struct variable_rec var; char *str; int inum; double rnum; struct cset_rec *semi; struct element_rec elt; struct expr_rec *cexpr; } u; }

user_defined_types: struct value_rec { int admin_nr; int ref_count; void *dptr; int tag; union { char *str; int inum; double rnum; struct value_list_rec *tuple; int slat; struct int_list_rec *elat; struct value_rec *free; } u; }

user_defined_types: struct variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec *def; }

user_defined_types: struct value_list_rec { int size; int room; struct value_rec **array; }

user_defined_types: struct int_list_rec { int size; int room; int *array; }

user_defined_types: struct meta_alt_rec { struct expr_rec *e; int number; }

user_defined_types: struct element_def_list_rec { int size; int room; struct element_def_rec **array; }


decompiled_code:
void __fastcall determine_follow_sets_in_rule(__int64 a1)
{
if ( (*(_BYTE *)(a1 + 16) & 6) == 0 )
determine_follow_sets_in_alts(a1, *(_QWORD *)(a1 + 8));
}

original_code:
static void determine_follow_sets_in_rule (rule srule)
 { if ((srule -> kind & 2) ||
       (srule -> kind & 4)) return;
   determine_follow_sets_in_alts (srule, srule -> alts);
 }

canonical_original_code:
static void determine_follow_sets_in_rule(struct rule_rec *srule)
 { if ((srule -> kind & 2) ||
       (srule -> kind & 4)) return;
   determine_follow_sets_in_alts (srule, srule -> alts);
 }

user_defined_types: struct rule_rec { char *nonterminal; struct alt_list_rec *alts; int kind; int empty; int lex; int ext; int number; int placeholder; int startswithlayout; int endsinlayout; char *first; char *follow; struct pos_list_rec *proto_display; int reachable; int has_sons; int goal; struct lextree_rec *rev_tree; }

user_defined_types: struct alt_list_rec { int size; int room; struct alt_rec **array; }

user_defined_types: struct lextree_rec { char *remainder; struct lexend_list_rec *prods; struct lextree_list_rec *tails; }

user_defined_types: struct lextree_list_rec { int size; int room; struct lextree_rec **array; }

user_defined_types: struct pos_list_rec { int size; int room; struct pos_rec **array; }

user_defined_types: struct lexend_rec { int nodenr; struct int_list_rec *valuenrs; }

user_defined_types: struct pos_rec { int kind; struct expr_rec *ex; int type; struct element_def_rec *lat_repr; }

user_defined_types: struct call_rec { char *nonterminal; struct pos_list_rec *display; struct rule_rec *def; }

user_defined_types: struct meta_rule_rec { char *nonterminal; struct meta_alt_list_rec *alts; int ext; int type; int kind; int empty; int number; struct value_rec *mvalue; int reachable; struct element_def_rec *lat_repr; int needs_rec; int needs_recbup; }

user_defined_types: struct meta_alt_list_rec { int size; int room; struct meta_alt_rec **array; }

user_defined_types: struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec *set; }

user_defined_types: struct element_set_rec { int number; struct element_def_list_rec *defs; }


decompiled_code:
void determine_follow_sets_in_rules()
{
__int64 v0; // rbx
__int64 v1; // rdi

if ( nr_of_rules > 0 )
{
v0 = 0LL;
do
{
v1 = *(_QWORD *)(all_rules + 8 * v0++);
determine_follow_sets_in_rule(v1);
}
while ( nr_of_rules > (int)v0 );
}
}

canonical_decompiled_code:
void func20()
{
__int64 v0; // rbx
__int64 v1; // rdi

if ( nr_of_rules > 0 )
{
v0 = 0LL;
do
{
v1 = *(_QWORD *)(all_rules + 8 * v0++);
func19(v1);
}
while ( nr_of_rules > (int)v0 );
}
}

original_code:
static void determine_follow_sets_in_rules ()
 { int ix;
   for (ix = 0; ix < nr_of_rules; ix++)
      determine_follow_sets_in_rule (all_rules[ix]);
 }

canonical_original_code:
static void determine_follow_sets_in_rules()
 { int ix;
   for (ix = 0; ix < nr_of_rules; ix++)
      determine_follow_sets_in_rule (all_rules[ix]);
 }


decompiled_code:
__int64 initiate_follow_sets()
{
__int64 v0; // rbx
__int64 result; // rax
int v2; // ecx
__int64 v3; // rbx
__int16 v4[5]; // [rsp+Eh] [rbp-Ah] BYREF

v4[0] = 132;
v0 = *(_QWORD *)(start_rule + 48LL);
result = addto_names(v4);
v2 = placeholderflag;
*(_QWORD *)(v0 + 56) = result;
if ( v2 )
{
v4[0] = 60;
v3 = lookup_syntax_rule("layout");
result = addto_names(v4);
*(_QWORD *)(v3 + 56) = result;
}
return result;
}

canonical_decompiled_code:
__int64 func21()
{
__int64 v0; // rbx
__int64 result; // rax
int v2; // ecx
__int64 v3; // rbx
__int16 v4[5]; // [rsp+Eh] [rbp-Ah] BYREF

v4[0] = 132;
v0 = *(_QWORD *)(start_rule + 48LL);
result = addto_names(v4);
v2 = placeholderflag;
*(_QWORD *)(v0 + 56) = result;
if ( v2 )
{
v4[0] = 60;
v3 = lookup_syntax_rule("layout");
result = addto_names(v4);
*(_QWORD *)(v3 + 56) = result;
}
return result;
}

original_code:
static void initiate_follow_sets ()
 { char buf[2];
   buf[0] = '\204';
   buf[1] = '\0';
   start_rule -> u.call.def -> follow = addto_names (buf);
   if (!placeholderflag) return;
   buf[0] = "<|>"[0];
   if ("<|"[0] != buf[0])
      { buf[1] = "<|"[0];
        buf[2] = '\0';
      }
   else buf[1] = '\0';
   lookup_syntax_rule ("layout") -> follow = addto_names (buf);
 }

canonical_original_code:
static void initiate_follow_sets()
 { char buf[2];
   buf[0] = '\204';
   buf[1] = '\0';
   start_rule -> u.call.def -> follow = addto_names (buf);
   if (!placeholderflag) return;
   buf[0] = "<|>"[0];
   if ("<|"[0] != buf[0])
      { buf[1] = "<|"[0];
        buf[2] = '\0';
      }
   else buf[1] = '\0';
   lookup_syntax_rule ("layout") -> follow = addto_names (buf);
 }

variable_types:
buf
char [2]


decompiled_code:
__int64 determine_follow_sets()
{
unsigned int v0; // ebp

v0 = 0;
warning("determining follow sets...");
initiate_follow_sets();
do
{
change = 0;
++v0;
determine_follow_sets_in_rules();
}
while ( change );
return hint("used %d passes for follow sets", v0);
}

canonical_decompiled_code:
__int64 func22()
{
unsigned int v0; // ebp

v0 = 0;
warning("determining follow sets...");
func21();
do
{
change = 0;
++v0;
func20();
}
while ( change );
return hint("used %d passes for follow sets", v0);
}

original_code:
static void determine_follow_sets ()
 { int nrpasses = 0;
   warning ("determining follow sets...");
   initiate_follow_sets ();
   nrpasses = 0;
   do
      { change = 0;
        nrpasses++;
        determine_follow_sets_in_rules ();
      }
   while (change);
   hint ("used %d passes for follow sets", nrpasses);
 }

canonical_original_code:
static void determine_follow_sets()
 { int nrpasses = 0;
   warning ("determining follow sets...");
   initiate_follow_sets ();
   nrpasses = 0;
   do
      { change = 0;
        nrpasses++;
        determine_follow_sets_in_rules ();
      }
   while (change);
   hint ("used %d passes for follow sets", nrpasses);
 }

variable_types: nrpasses int


decompiled_code:
const char *__fastcall report_director_set(const char **a1)
{
const char *result; // rax
__int64 v2; // rbx
__int64 v3; // rax

wlog("first (%s) = %s", *a1, a1[6]);
wlog("follow (%s) = %s", *a1, a1[7]);
result = a1[1];
if ( *(int *)result > 0 )
{
v2 = 0LL;
do
{
v3 = *(_QWORD *)(*((_QWORD *)result + 1) + 8 * v2++);
wlog("direct_alt (%d) = %s", (unsigned int)v2, *(const char **)(v3 + 56));
result = a1[1];
}
while ( *(_DWORD *)result > (int)v2 );
}
return result;
}

canonical_decompiled_code:
const char *__fastcall func23(const char **a1)
{
const char *result; // rax
__int64 v2; // rbx
__int64 v3; // rax

wlog("first (%s) = %s", *a1, a1[6]);
wlog("follow (%s) = %s", *a1, a1[7]);
result = a1[1];
if ( *(int *)result > 0 )
{
v2 = 0LL;
do
{
v3 = *(_QWORD *)(*((_QWORD *)result + 1) + 8 * v2++);
wlog("direct_alt (%d) = %s", (unsigned int)v2, *(const char **)(v3 + 56));
result = a1[1];
}
while ( *(_DWORD *)result > (int)v2 );
}
return result;
}

original_code:
static void report_director_set (rule srule)
 { int ix;
   wlog ("first (%s) = %s", srule -> nonterminal, srule -> first);
   wlog ("follow (%s) = %s", srule -> nonterminal, srule -> follow);
   for (ix = 0; ix < srule -> alts -> size; ix++)
      wlog ("direct_alt (%d) = %s", ix + 1,
     srule -> alts -> array[ix] -> director);
 }

canonical_original_code:
static void report_director_set(struct rule_rec *srule)
 { int ix;
   wlog ("first (%s) = %s", srule -> nonterminal, srule -> first);
   wlog ("follow (%s) = %s", srule -> nonterminal, srule -> follow);
   for (ix = 0; ix < srule -> alts -> size; ix++)
      wlog ("direct_alt (%d) = %s", ix + 1,
     srule -> alts -> array[ix] -> director);
 }

user_defined_types: struct lexend_list_rec { int size; int room; struct lexend_rec **array; }

user_defined_types: struct alt_rec { struct pos_list_rec *display; struct member_list_rec *members; int number; int nodenr; int nrsons; struct affix_rec *locals; int empty; char *first; char *director; int rule_nr; }

user_defined_types: struct member_list_rec { int size; int room; struct member_rec **array; }

user_defined_types: struct member_rec { int empty; int followlayout; char *first; int number; int sonnr; int tag; union { struct call_rec call; char *terminal; struct semiterminal_rec semi; } u; }

user_defined_types: struct expr_rec { int tag; union { struct affix_rec *single; struct affix_list_rec *compos; struct affix_list_rec *concat; struct affix_list_rec *uni; } u; }

user_defined_types: struct semiterminal_rec { struct cset_rec *set; struct pos_list_rec *display; }

user_defined_types: struct affix_rec { char *name; int type; struct affix_rec *next; struct value_rec *val; int ref_count; int reachable; int tag; union { struct variable_rec var; char *str; int inum; double rnum; struct cset_rec *semi; struct element_rec elt; struct expr_rec *cexpr; } u; }

user_defined_types: struct affix_list_rec { int size; int room; struct affix_rec **array; }

user_defined_types: struct value_rec { int admin_nr; int ref_count; void *dptr; int tag; union { char *str; int inum; double rnum; struct value_list_rec *tuple; int slat; struct int_list_rec *elat; struct value_rec *free; } u; }

user_defined_types: struct variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec *def; }

user_defined_types: struct element_rec { char *eltnm; struct element_def_rec *def; }

user_defined_types: struct cset_rec { int kind; char *str; }


decompiled_code:
const char *report_director_sets()
{
const char *result; // rax
__int64 v1; // rbx
const char **v2; // rdi

result = (const char *)nr_of_rules;
if ( nr_of_rules > 0 )
{
v1 = 0LL;
do
{
v2 = *(const char ***)(all_rules + 8 * v1++);
result = report_director_set(v2);
}
while ( nr_of_rules > (int)v1 );
}
return result;
}

canonical_decompiled_code:
const char *func24()
{
const char *result; // rax
__int64 v1; // rbx
const char **v2; // rdi

result = (const char *)nr_of_rules;
if ( nr_of_rules > 0 )
{
v1 = 0LL;
do
{
v2 = *(const char ***)(all_rules + 8 * v1++);
result = func23(v2);
}
while ( nr_of_rules > (int)v1 );
}
return result;
}

original_code:
static void report_director_sets ()
 { int ix;
   for (ix = 0; ix < nr_of_rules; ix++)
      report_director_set (all_rules[ix]);
 }

canonical_original_code:
static void report_director_sets()
 { int ix;
   for (ix = 0; ix < nr_of_rules; ix++)
      report_director_set (all_rules[ix]);
 }


decompiled_code:
__int64 __fastcall add_first_sets_for_member(unsigned __int8 *a1, __int64 a2, __int64 a3, __int64 a4)
{
__int64 v5; // rdi
__int64 result; // rax

v5 = *(unsigned int *)(a2 + 24);
if ( (int)v5 <= 2 )
{
if ( (int)v5 > 0 )
return addto_set(a1, *(unsigned __int8 **)(a2 + 8));
if ( !(_DWORD)v5 )
return add_first_sets_for_call_isra_0(a1, *(_QWORD *)(a2 + 48));
return bad_tag(v5, "add_first_sets_for_member", a3, a4, a1);
}
if ( (_DWORD)v5 != 3 )
return bad_tag(v5, "add_first_sets_for_member", a3, a4, a1);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func26(unsigned __int8 *a1, __int64 a2, __int64 a3, __int64 a4)
{
__int64 v5; // rdi
__int64 result; // rax

v5 = *(unsigned int *)(a2 + 24);
if ( (int)v5 <= 2 )
{
if ( (int)v5 > 0 )
return func2(a1, *(unsigned __int8 **)(a2 + 8));
if ( !(_DWORD)v5 )
return func25(a1, *(_QWORD *)(a2 + 48));
return bad_tag(v5, "add_first_sets_for_member", a3, a4, a1);
}
if ( (_DWORD)v5 != 3 )
return bad_tag(v5, "add_first_sets_for_member", a3, a4, a1);
return result;
}

original_code:
static void add_first_sets_for_member (char *dst, member m)
 { switch (m -> tag)
      { case 0: add_first_sets_for_call (dst, m); break;
        case 1:
        case 2: addto_set (dst, m -> first);
        case 3: break;
        default: bad_tag (m -> tag, "add_first_sets_for_member");
      };
 }

canonical_original_code:
static void add_first_sets_for_member(char *dst, struct member_rec *m)
 { switch (m -> tag)
      { case 0: add_first_sets_for_call (dst, m); break;
        case 1:
        case 2: addto_set (dst, m -> first);
        case 3: break;
        default: bad_tag (m -> tag, "add_first_sets_for_member");
      };
 }

variable_types:
dst
char *

user_defined_types: struct call_rec { char *nonterminal; struct pos_list_rec *display; struct rule_rec *def; }

user_defined_types: struct pos_list_rec { int size; int room; struct pos_rec **array; }

user_defined_types: struct rule_rec { char *nonterminal; struct alt_list_rec *alts; int kind; int empty; int lex; int ext; int number; int placeholder; int startswithlayout; int endsinlayout; char *first; char *follow; struct pos_list_rec *proto_display; int reachable; int has_sons; int goal; struct lextree_rec *rev_tree; }

user_defined_types: struct alt_list_rec { int size; int room; struct alt_rec **array; }

user_defined_types: struct lextree_rec { char *remainder; struct lexend_list_rec *prods; struct lextree_list_rec *tails; }

user_defined_types: struct pos_rec { int kind; struct expr_rec *ex; int type; struct element_def_rec *lat_repr; }

user_defined_types: struct lextree_list_rec { int size; int room; struct lextree_rec **array; }

user_defined_types: struct lexend_rec { int nodenr; struct int_list_rec *valuenrs; }

user_defined_types: struct value_list_rec { int size; int room; struct value_rec **array; }

user_defined_types: struct int_list_rec { int size; int room; int *array; }

user_defined_types: struct meta_alt_rec { struct expr_rec *e; int number; }

user_defined_types: struct element_def_list_rec { int size; int room; struct element_def_rec **array; }


decompiled_code:
__int64 __fastcall add_first_sets_for_alt(unsigned __int8 *a1, __int64 a2)
{
unsigned __int8 *v3; // rsi
_DWORD *v4; // rdx
__int64 v5; // rcx
unsigned __int8 *v6; // rbp
__int64 v7; // rax
unsigned __int8 v9[280]; // [rsp+0h] [rbp-118h] BYREF

v3 = *(unsigned __int8 **)(a2 + 48);
v9[0] = 0;
addto_set(v9, v3);
add_first_sets_for_members(v9, *(_QWORD *)(a2 + 8), v4, v5);
v6 = *(unsigned __int8 **)(a2 + 48);
if ( !v6 || strcmp(*(const char **)(a2 + 48), (const char *)v9) )
{
v7 = addto_names(v9);
change = 1;
*(_QWORD *)(a2 + 48) = v7;
v6 = (unsigned __int8 *)v7;
}
return addto_set(a1, v6);
}

canonical_decompiled_code:
__int64 __fastcall func28(unsigned __int8 *a1, __int64 a2)
{
unsigned __int8 *v3; // rsi
_DWORD *v4; // rdx
__int64 v5; // rcx
unsigned __int8 *v6; // rbp
__int64 v7; // rax
unsigned __int8 v9[280]; // [rsp+0h] [rbp-118h] BYREF

v3 = *(unsigned __int8 **)(a2 + 48);
v9[0] = 0;
func2(v9, v3);
func27(v9, *(_QWORD *)(a2 + 8), v4, v5);
v6 = *(unsigned __int8 **)(a2 + 48);
if ( !v6 || strcmp(*(const char **)(a2 + 48), (const char *)v9) )
{
v7 = addto_names(v9);
change = 1;
*(_QWORD *)(a2 + 48) = v7;
v6 = (unsigned __int8 *)v7;
}
return func2(a1, v6);
}

original_code:
static void add_first_sets_for_alt (char *dst, alt a)
 { char altset[256];
   altset[0] = '\0';
   addto_set (altset, a -> first);
   add_first_sets_for_members (altset, a -> members);
   if ((a -> first == ((string) ((void *)0))) ||
       (strcmp (a -> first, altset) != 0))
      { a -> first = addto_names (altset);
        change = 1;
      };
   addto_set (dst, a -> first);
 }

canonical_original_code:
static void add_first_sets_for_alt(char *dst, struct alt_rec *a)
 { char altset[256];
   altset[0] = '\0';
   addto_set (altset, a -> first);
   add_first_sets_for_members (altset, a -> members);
   if ((a -> first == ((string) ((void *)0))) ||
       (strcmp (a -> first, altset) != 0))
      { a -> first = addto_names (altset);
        change = 1;
      };
   addto_set (dst, a -> first);
 }

variable_types: struct alt_rec { struct pos_list_rec { int size; int room; struct pos_rec { int kind; struct expr_rec { int tag; union { struct affix_rec { char *name; int type; struct affix_rec *next; struct value_rec { int admin_nr; int ref_count; void *dptr; int tag; union { char *str; int inum; double rnum; struct value_list_rec { int size; int room; struct value_rec **array; } *tuple; int slat; struct int_list_rec { int size; int room; int *array; } *elat; struct value_rec *free; } u; } *val; int ref_count; int reachable; int tag; union { struct variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec { char *nonterminal; struct meta_alt_list_rec { int size; int room; struct meta_alt_rec { struct expr_rec *e; int number; } **array; } *alts; int ext; int type; int kind; int empty; int number; struct value_rec *mvalue; int reachable; struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec { int number; struct element_def_list_rec { int size; int room; struct element_def_rec **array; } *defs; } *set; } *lat_repr; int needs_rec; int needs_recbup; } *def; } var; char *str; int inum; double rnum; struct cset_rec { int kind; char *str; } *semi; struct element_rec { char *eltnm; struct element_def_rec *def; } elt; struct expr_rec *cexpr; } u; } *single; struct affix_list_rec { int size; int room; struct affix_rec **array; } *compos; struct affix_list_rec *concat; struct affix_list_rec *uni; } u; } *ex; int type; struct element_def_rec *lat_repr; } **array; } *display; struct member_list_rec { int size; int room; struct member_rec { int empty; int followlayout; char *first; int number; int sonnr; int tag; union { struct call_rec { char *nonterminal; struct pos_list_rec *display; struct rule_rec { char *nonterminal; struct alt_list_rec { int size; int room; struct alt_rec **array; } *alts; int kind; int empty; int lex; int ext; int number; int placeholder; int startswithlayout; int endsinlayout; char *first; char *follow; struct pos_list_rec *proto_display; int reachable; int has_sons; int goal; struct lextree_rec { char *remainder; struct lexend_list_rec { int size; int room; struct lexend_rec { int nodenr; struct int_list_rec *valuenrs; } **array; } *prods; struct lextree_list_rec { int size; int room; struct lextree_rec **array; } *tails; } *rev_tree; } *def; } call; char *terminal; struct semiterminal_rec { struct cset_rec *set; struct pos_list_rec *display; } semi; } u; } **array; } *members; int number; int nodenr; int nrsons; struct affix_rec *locals; int empty; char *first; char *director; int rule_nr; } *

variable_types:
altset
char [256]

user_defined_types: struct alt_rec { struct pos_list_rec *display; struct member_list_rec *members; int number; int nodenr; int nrsons; struct affix_rec *locals; int empty; char *first; char *director; int rule_nr; }

user_defined_types: struct member_list_rec { int size; int room; struct member_rec **array; }

user_defined_types: struct member_rec { int empty; int followlayout; char *first; int number; int sonnr; int tag; union { struct call_rec call; char *terminal; struct semiterminal_rec semi; } u; }

user_defined_types: struct expr_rec { int tag; union { struct affix_rec *single; struct affix_list_rec *compos; struct affix_list_rec *concat; struct affix_list_rec *uni; } u; }

user_defined_types: struct affix_rec { char *name; int type; struct affix_rec *next; struct value_rec *val; int ref_count; int reachable; int tag; union { struct variable_rec var; char *str; int inum; double rnum; struct cset_rec *semi; struct element_rec elt; struct expr_rec *cexpr; } u; }

user_defined_types: struct lexend_list_rec { int size; int room; struct lexend_rec **array; }

user_defined_types: struct meta_rule_rec { char *nonterminal; struct meta_alt_list_rec *alts; int ext; int type; int kind; int empty; int number; struct value_rec *mvalue; int reachable; struct element_def_rec *lat_repr; int needs_rec; int needs_recbup; }

user_defined_types: struct meta_alt_list_rec { int size; int room; struct meta_alt_rec **array; }

user_defined_types: struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec *set; }

user_defined_types: struct element_set_rec { int number; struct element_def_list_rec *defs; }


original_code:
static void find_first_sets_for_rule (rule srule)
 { char ruleset[256];
   int ix;
   if (srule -> ext) return;
   if (srule -> kind & 2) return;
   if (srule -> kind & 4) return;
   ruleset[0] = '\0';
   addto_set (ruleset, srule -> first);
   for (ix = 0; ix < srule -> alts -> size; ix++)
      add_first_sets_for_alt (ruleset, srule -> alts -> array[ix]);
   if ((srule -> first == ((string) ((void *)0))) ||
       (strcmp (srule -> first, ruleset) != 0))
      { srule -> first = addto_names (ruleset);
        change = 1;
      };
 }

canonical_original_code:
static void find_first_sets_for_rule(struct rule_rec *srule)
 { char ruleset[256];
   int ix;
   if (srule -> ext) return;
   if (srule -> kind & 2) return;
   if (srule -> kind & 4) return;
   ruleset[0] = '\0';
   addto_set (ruleset, srule -> first);
   for (ix = 0; ix < srule -> alts -> size; ix++)
      add_first_sets_for_alt (ruleset, srule -> alts -> array[ix]);
   if ((srule -> first == ((string) ((void *)0))) ||
       (strcmp (srule -> first, ruleset) != 0))
      { srule -> first = addto_names (ruleset);
        change = 1;
      };
 }

variable_types:
ruleset
char [256]

user_defined_types: struct rule_rec { char *nonterminal; struct alt_list_rec *alts; int kind; int empty; int lex; int ext; int number; int placeholder; int startswithlayout; int endsinlayout; char *first; char *follow; struct pos_list_rec *proto_display; int reachable; int has_sons; int goal; struct lextree_rec *rev_tree; }

user_defined_types: struct alt_list_rec { int size; int room; struct alt_rec **array; }

user_defined_types: struct lextree_rec { char *remainder; struct lexend_list_rec *prods; struct lextree_list_rec *tails; }

user_defined_types: struct pos_list_rec { int size; int room; struct pos_rec **array; }

user_defined_types: struct pos_rec { int kind; struct expr_rec *ex; int type; struct element_def_rec *lat_repr; }

user_defined_types: struct call_rec { char *nonterminal; struct pos_list_rec *display; struct rule_rec *def; }

user_defined_types: struct semiterminal_rec { struct cset_rec *set; struct pos_list_rec *display; }

user_defined_types: struct affix_list_rec { int size; int room; struct affix_rec **array; }

user_defined_types: struct value_rec { int admin_nr; int ref_count; void *dptr; int tag; union { char *str; int inum; double rnum; struct value_list_rec *tuple; int slat; struct int_list_rec *elat; struct value_rec *free; } u; }

user_defined_types: struct variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec *def; }

user_defined_types: struct element_rec { char *eltnm; struct element_def_rec *def; }

user_defined_types: struct cset_rec { int kind; char *str; }


decompiled_code:
void find_first_sets_for_rules()
{
__int64 v0; // rbx
__int64 v1; // rdi

if ( nr_of_rules > 0 )
{
v0 = 0LL;
do
{
v1 = *(_QWORD *)(all_rules + 8 * v0++);
find_first_sets_for_rule(v1);
}
while ( nr_of_rules > (int)v0 );
}
}

canonical_decompiled_code:
void func30()
{
__int64 v0; // rbx
__int64 v1; // rdi

if ( nr_of_rules > 0 )
{
v0 = 0LL;
do
{
v1 = *(_QWORD *)(all_rules + 8 * v0++);
func29(v1);
}
while ( nr_of_rules > (int)v0 );
}
}

original_code:
static void find_first_sets_for_rules ()
 { int ix;
   for (ix = 0; ix < nr_of_rules; ix++)
      find_first_sets_for_rule (all_rules[ix]);
 }

canonical_original_code:
static void find_first_sets_for_rules()
 { int ix;
   for (ix = 0; ix < nr_of_rules; ix++)
      find_first_sets_for_rule (all_rules[ix]);
 }


decompiled_code:
__int64 __fastcall determine_first_sets(__int64 a1, __int64 a2)
{
unsigned int v2; // ebp
__int64 v3; // rdx

v2 = 0;
warning("determining first sets...");
initial_first_sets_in_rules((__int64)"determining first sets...", a2, v3);
do
{
change = 0;
++v2;
find_first_sets_for_rules();
}
while ( change );
return hint("used %d passes for first sets", v2);
}

canonical_decompiled_code:
__int64 __fastcall func31(__int64 a1, __int64 a2)
{
unsigned int v2; // ebp
__int64 v3; // rdx

v2 = 0;
warning("determining first sets...");
func13((__int64)"determining first sets...", a2, v3);
do
{
change = 0;
++v2;
func30();
}
while ( change );
return hint("used %d passes for first sets", v2);
}

original_code:
static void determine_first_sets ()
 { int nrpasses = 0;
   warning ("determining first sets...");
   initial_first_sets_in_rules ();
   do
      { change = 0;
        nrpasses++;
        find_first_sets_for_rules ();
      }
   while (change);
   hint ("used %d passes for first sets", nrpasses);
 }

canonical_original_code:
static void determine_first_sets()
 { int nrpasses = 0;
   warning ("determining first sets...");
   initial_first_sets_in_rules ();
   do
      { change = 0;
        nrpasses++;
        find_first_sets_for_rules ();
      }
   while (change);
   hint ("used %d passes for first sets", nrpasses);
 }


decompiled_code:
const char *__fastcall determine_lookahead_sets(__int64 a1, __int64 a2)
{
const char *result; // rax

determine_first_sets(a1, a2);
determine_follow_sets();
determine_director_sets();
result = (const char *)full_verbose;
if ( full_verbose )
result = report_director_sets();
return result;
}

canonical_decompiled_code:
const char *__fastcall func32(__int64 a1, __int64 a2)
{
const char *result; // rax

func31(a1, a2);
func22();
func8();
result = (const char *)full_verbose;
if ( full_verbose )
result = func24();
return result;
}

original_code:
void determine_lookahead_sets ()
 { determine_first_sets ();
   determine_follow_sets ();
   determine_director_sets ();
   if (full_verbose) report_director_sets ();
 }

canonical_original_code:
void determine_lookahead_sets()
 { determine_first_sets ();
   determine_follow_sets ();
   determine_director_sets ();
   if (full_verbose) report_director_sets ();
 }


decompiled_code:
__int64 __fastcall gather_lcin_director_set(__int64 a1, int *a2, int a3, __int64 a4)
{
int v4; // er12
unsigned __int8 v6[280]; // [rsp+0h] [rbp-118h] BYREF

v4 = a3 + 1;
v6[0] = 0;
add_first_of_members_to_follow_set((__int64)a2, a3 + 1, v6, a4);
try_add_rule_set_to_follow_set(a1, a2, v4, v6);
return addto_names(v6);
}

canonical_decompiled_code:
__int64 __fastcall func33(__int64 a1, int *a2, int a3, __int64 a4)
{
int v4; // er12
unsigned __int8 v6[280]; // [rsp+0h] [rbp-118h] BYREF

v4 = a3 + 1;
v6[0] = 0;
func15((__int64)a2, a3 + 1, v6, a4);
try_add_rule_set_to_follow_set(a1, a2, v4, v6);
return addto_names(v6);
}

original_code:
char *gather_lcin_director_set (rule srule, member_list mems, int j)
 { char fset[256];
   fset[0] = '\0';
   add_first_of_members_to_follow_set (mems, j + 1, fset);
   try_add_rule_set_to_follow_set (srule, mems, j + 1, fset);
   return (addto_names (fset));
 }

canonical_original_code:
char *gather_lcin_director_set(struct rule_rec *srule, struct member_list_rec *mems, int j)
 { char fset[256];
   fset[0] = '\0';
   add_first_of_members_to_follow_set (mems, j + 1, fset);
   try_add_rule_set_to_follow_set (srule, mems, j + 1, fset);
   return (addto_names (fset));
 }

variable_types: j int

return_type: char *

user_defined_types: struct lexend_list_rec { int size; int room; struct lexend_rec **array; }

user_defined_types: struct lextree_list_rec { int size; int room; struct lextree_rec **array; }

user_defined_types: struct alt_rec { struct pos_list_rec *display; struct member_list_rec *members; int number; int nodenr; int nrsons; struct affix_rec *locals; int empty; char *first; char *director; int rule_nr; }

user_defined_types: struct member_list_rec { int size; int room; struct member_rec **array; }

user_defined_types: struct lexend_rec { int nodenr; struct int_list_rec *valuenrs; }

user_defined_types: struct member_rec { int empty; int followlayout; char *first; int number; int sonnr; int tag; union { struct call_rec call; char *terminal; struct semiterminal_rec semi; } u; }

user_defined_types: struct expr_rec { int tag; union { struct affix_rec *single; struct affix_list_rec *compos; struct affix_list_rec *concat; struct affix_list_rec *uni; } u; }

user_defined_types: struct affix_rec { char *name; int type; struct affix_rec *next; struct value_rec *val; int ref_count; int reachable; int tag; union { struct variable_rec var; char *str; int inum; double rnum; struct cset_rec *semi; struct element_rec elt; struct expr_rec *cexpr; } u; }

user_defined_types: struct value_list_rec { int size; int room; struct value_rec **array; }

user_defined_types: struct int_list_rec { int size; int room; int *array; }

user_defined_types: struct meta_alt_rec { struct expr_rec *e; int number; }

user_defined_types: struct element_def_list_rec { int size; int room; struct element_def_rec **array; }


decompiled_code:
int __fastcall enter_meta_rule(const char **a1)
{
const char ***v1; // rbx
const char *v2; // r12
__int64 *v3; // rbp
int result; // eax
const char ***v5; // rax

v1 = (const char ***)meta_root;
if ( meta_root )
{
v2 = *a1;
do
{
v3 = (__int64 *)(v1 + 1);
result = strcmp(v2, **v1);
if ( result >= 0 )
{
if ( !result )
return result;
v3 = (__int64 *)(v1 + 2);
}
v1 = (const char ***)*v3;
}
while ( *v3 );
}
else
{
v3 = &meta_root;
}
v5 = (const char ***)ckmalloc(24LL);
*v3 = (__int64)v5;
*v5 = a1;
v5[1] = 0LL;
*(_QWORD *)(*v3 + 16) = 0LL;
return 1;
}

canonical_decompiled_code:
int __fastcall func0(const char **a1)
{
const char ***v1; // rbx
const char *v2; // r12
__int64 *v3; // rbp
int result; // eax
const char ***v5; // rax

v1 = (const char ***)meta_root;
if ( meta_root )
{
v2 = *a1;
do
{
v3 = (__int64 *)(v1 + 1);
result = strcmp(v2, **v1);
if ( result >= 0 )
{
if ( !result )
return result;
v3 = (__int64 *)(v1 + 2);
}
v1 = (const char ***)*v3;
}
while ( *v3 );
}
else
{
v3 = &meta_root;
}
v5 = (const char ***)ckmalloc(24LL);
*v3 = (__int64)v5;
*v5 = a1;
v5[1] = 0LL;
*(_QWORD *)(*v3 + 16) = 0LL;
return 1;
}

original_code:
int enter_meta_rule (meta_rule node)
 { meta_tree *ptr = &meta_root;
   while (1)
      { int cond;
        if (*ptr == ((meta_tree) ((void *)0)))
    { *ptr = (meta_tree) ckmalloc (sizeof (struct meta_tree_rec));
      (*ptr) -> node = node;
      (*ptr) -> left = ((meta_tree) ((void *)0));
      (*ptr) -> right = ((meta_tree) ((void *)0));
      return (1);
    };
        cond = strcmp (node -> nonterminal,
         (*ptr) -> node -> nonterminal);
        if (cond < 0) ptr = &((*ptr) -> left);
        else if (cond > 0) ptr = &((*ptr) -> right);
        else return (0);
      }
 }

canonical_original_code:
int enter_meta_rule(struct meta_rule_rec *node)
 { struct meta_tree_rec **ptr = &meta_root;
   while (1)
      { int cond;
        if (*ptr == ((meta_tree) ((void *)0)))
    { *ptr = (struct meta_tree_rec *) ckmalloc (sizeof (struct meta_tree_rec));
      (*ptr) -> node = node;
      (*ptr) -> left = ((meta_tree) ((void *)0));
      (*ptr) -> right = ((meta_tree) ((void *)0));
      return (1);
    };
        cond = strcmp (node -> nonterminal,
         (*ptr) -> node -> nonterminal);
        if (cond < 0) ptr = &((*ptr) -> left);
        else if (cond > 0) ptr = &((*ptr) -> right);
        else return (0);
      }
 }

variable_types: struct meta_tree_rec { struct meta_rule_rec { char *nonterminal; struct meta_alt_list_rec { int size; int room; struct meta_alt_rec { struct expr_rec { int tag; union { struct affix_rec { char *name; int type; struct affix_rec *next; struct value_rec { int admin_nr; int ref_count; void *dptr; int tag; union { char *str; int inum; double rnum; struct value_list_rec { int size; int room; struct value_rec **array; } *tuple; int slat; struct int_list_rec { int size; int room; int *array; } *elat; struct value_rec *free; } u; } *val; int ref_count; int reachable; int tag; union { struct variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec *def; } var; char *str; int inum; double rnum; struct cset_rec { int kind; char *str; } *semi; struct element_rec { char *eltnm; struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec { int number; struct element_def_list_rec { int size; int room; struct element_def_rec **array; } *defs; } *set; } *def; } elt; struct expr_rec *cexpr; } u; } *single; struct affix_list_rec { int size; int room; struct affix_rec **array; } *compos; struct affix_list_rec *concat; struct affix_list_rec *uni; } u; } *e; int number; } **array; } *alts; int ext; int type; int kind; int empty; int number; struct value_rec *mvalue; int reachable; struct element_def_rec *lat_repr; int needs_rec; int needs_recbup; } *node; struct meta_tree_rec *left; struct meta_tree_rec *right; } **

variable_types: cond int

return_type: int

user_defined_types: struct meta_tree_rec { struct meta_rule_rec *node; struct meta_tree_rec *left; struct meta_tree_rec *right; }

user_defined_types: struct meta_rule_rec { char *nonterminal; struct meta_alt_list_rec *alts; int ext; int type; int kind; int empty; int number; struct value_rec *mvalue; int reachable; struct element_def_rec *lat_repr; int needs_rec; int needs_recbup; }

user_defined_types: struct meta_alt_list_rec { int size; int room; struct meta_alt_rec **array; }

user_defined_types: struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec *set; }

user_defined_types: struct element_set_rec { int number; struct element_def_list_rec *defs; }


decompiled_code:
const char **__fastcall lookup_meta_rule(char *s1)
{
__int64 v1; // r12
const char **v2; // rbx
int v3; // eax

v1 = meta_root;
if ( !meta_root )
return (const char **)v1;
while ( 1 )
{
while ( 1 )
{
v2 = *(const char ***)v1;
v3 = strcmp(s1, **(const char ***)v1);
if ( v3 >= 0 )
break;
v1 = *(_QWORD *)(v1 + 8);
if ( !v1 )
return (const char **)v1;
}
if ( !v3 )
break;
v1 = *(_QWORD *)(v1 + 16);
if ( !v1 )
return (const char **)v1;
}
return v2;
}

canonical_decompiled_code:
const char **__fastcall func1(char *s1)
{
__int64 v1; // r12
const char **v2; // rbx
int v3; // eax

v1 = meta_root;
if ( !meta_root )
return (const char **)v1;
while ( 1 )
{
while ( 1 )
{
v2 = *(const char ***)v1;
v3 = strcmp(s1, **(const char ***)v1);
if ( v3 >= 0 )
break;
v1 = *(_QWORD *)(v1 + 8);
if ( !v1 )
return (const char **)v1;
}
if ( !v3 )
break;
v1 = *(_QWORD *)(v1 + 16);
if ( !v1 )
return (const char **)v1;
}
return v2;
}

original_code:
meta_rule lookup_meta_rule (string nont)
 { meta_tree ptr = meta_root;
   while (1)
      { int cond;
        if (ptr == ((meta_tree) ((void *)0))) return (((meta_rule) ((void *)0)));
        cond = strcmp (nont, ptr -> node -> nonterminal);
        if (cond < 0) ptr = ptr -> left;
        else if (cond > 0) ptr = ptr -> right;
        else return (ptr -> node);
      };
 }

canonical_original_code:
struct meta_rule_rec *lookup_meta_rule(char *nont)
 { struct meta_tree_rec *ptr = meta_root;
   while (1)
      { int cond;
        if (ptr == ((meta_tree) ((void *)0))) return (((meta_rule) ((void *)0)));
        cond = strcmp (nont, ptr -> node -> nonterminal);
        if (cond < 0) ptr = ptr -> left;
        else if (cond > 0) ptr = ptr -> right;
        else return (ptr -> node);
      };
 }

variable_types:
nont
char *

variable_types: struct meta_tree_rec { struct meta_rule_rec { char *nonterminal; struct meta_alt_list_rec { int size; int room; struct meta_alt_rec { struct expr_rec { int tag; union { struct affix_rec { char *name; int type; struct affix_rec *next; struct value_rec { int admin_nr; int ref_count; void *dptr; int tag; union { char *str; int inum; double rnum; struct value_list_rec { int size; int room; struct value_rec **array; } *tuple; int slat; struct int_list_rec { int size; int room; int *array; } *elat; struct value_rec *free; } u; } *val; int ref_count; int reachable; int tag; union { struct variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec *def; } var; char *str; int inum; double rnum; struct cset_rec { int kind; char *str; } *semi; struct element_rec { char *eltnm; struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec { int number; struct element_def_list_rec { int size; int room; struct element_def_rec **array; } *defs; } *set; } *def; } elt; struct expr_rec *cexpr; } u; } *single; struct affix_list_rec { int size; int room; struct affix_rec **array; } *compos; struct affix_list_rec *concat; struct affix_list_rec *uni; } u; } *e; int number; } **array; } *alts; int ext; int type; int kind; int empty; int number; struct value_rec *mvalue; int reachable; struct element_def_rec *lat_repr; int needs_rec; int needs_recbup; } *node; struct meta_tree_rec *left; struct meta_tree_rec *right; } *

user_defined_types: struct value_rec { int admin_nr; int ref_count; void *dptr; int tag; union { char *str; int inum; double rnum; struct value_list_rec *tuple; int slat; struct int_list_rec *elat; struct value_rec *free; } u; }

user_defined_types: struct element_rec { char *eltnm; struct element_def_rec *def; }


decompiled_code:
int __fastcall enter_syntax_rule(const char **a1)
{
const char ***v1; // rbx
const char *v2; // r12
__int64 *v3; // rbp
int result; // eax
const char ***v5; // rax

v1 = (const char ***)rule_root;
if ( rule_root )
{
v2 = *a1;
do
{
v3 = (__int64 *)(v1 + 1);
result = strcmp(v2, **v1);
if ( result >= 0 )
{
if ( !result )
return result;
v3 = (__int64 *)(v1 + 2);
}
v1 = (const char ***)*v3;
}
while ( *v3 );
}
else
{
v3 = &rule_root;
}
v5 = (const char ***)ckmalloc(24LL);
*v3 = (__int64)v5;
*v5 = a1;
v5[1] = 0LL;
*(_QWORD *)(*v3 + 16) = 0LL;
return 1;
}

canonical_decompiled_code:
int __fastcall func2(const char **a1)
{
const char ***v1; // rbx
const char *v2; // r12
__int64 *v3; // rbp
int result; // eax
const char ***v5; // rax

v1 = (const char ***)rule_root;
if ( rule_root )
{
v2 = *a1;
do
{
v3 = (__int64 *)(v1 + 1);
result = strcmp(v2, **v1);
if ( result >= 0 )
{
if ( !result )
return result;
v3 = (__int64 *)(v1 + 2);
}
v1 = (const char ***)*v3;
}
while ( *v3 );
}
else
{
v3 = &rule_root;
}
v5 = (const char ***)ckmalloc(24LL);
*v3 = (__int64)v5;
*v5 = a1;
v5[1] = 0LL;
*(_QWORD *)(*v3 + 16) = 0LL;
return 1;
}

original_code:
int enter_syntax_rule (rule node)
 { rule_tree *ptr = &rule_root;
   while (1)
      { int cond;
        if (*ptr == ((rule_tree) ((void *)0)))
    { *ptr = (rule_tree) ckmalloc (sizeof (struct rule_tree_rec));
      (*ptr) -> node = node;
      (*ptr) -> left = ((rule_tree) ((void *)0));
      (*ptr) -> right = ((rule_tree) ((void *)0));
      return (1);
    };
        cond = strcmp (node -> nonterminal,
         (*ptr) -> node -> nonterminal);
        if (cond < 0) ptr = &((*ptr) -> left);
        else if (cond > 0) ptr = &((*ptr) -> right);
        else return (0);
      }
 }

canonical_original_code:
int enter_syntax_rule(struct rule_rec *node)
 { struct rule_tree_rec **ptr = &rule_root;
   while (1)
      { int cond;
        if (*ptr == ((rule_tree) ((void *)0)))
    { *ptr = (struct rule_tree_rec *) ckmalloc (sizeof (struct rule_tree_rec));
      (*ptr) -> node = node;
      (*ptr) -> left = ((rule_tree) ((void *)0));
      (*ptr) -> right = ((rule_tree) ((void *)0));
      return (1);
    };
        cond = strcmp (node -> nonterminal,
         (*ptr) -> node -> nonterminal);
        if (cond < 0) ptr = &((*ptr) -> left);
        else if (cond > 0) ptr = &((*ptr) -> right);
        else return (0);
      }
 }

variable_types: struct rule_tree_rec { struct rule_rec { char *nonterminal; struct alt_list_rec { int size; int room; struct alt_rec { struct pos_list_rec { int size; int room; struct pos_rec { int kind; struct expr_rec { int tag; union { struct affix_rec { char *name; int type; struct affix_rec *next; struct value_rec { int admin_nr; int ref_count; void *dptr; int tag; union { char *str; int inum; double rnum; struct value_list_rec { int size; int room; struct value_rec **array; } *tuple; int slat; struct int_list_rec { int size; int room; int *array; } *elat; struct value_rec *free; } u; } *val; int ref_count; int reachable; int tag; union { struct variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec { char *nonterminal; struct meta_alt_list_rec { int size; int room; struct meta_alt_rec { struct expr_rec *e; int number; } **array; } *alts; int ext; int type; int kind; int empty; int number; struct value_rec *mvalue; int reachable; struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec { int number; struct element_def_list_rec { int size; int room; struct element_def_rec **array; } *defs; } *set; } *lat_repr; int needs_rec; int needs_recbup; } *def; } var; char *str; int inum; double rnum; struct cset_rec { int kind; char *str; } *semi; struct element_rec { char *eltnm; struct element_def_rec *def; } elt; struct expr_rec *cexpr; } u; } *single; struct affix_list_rec { int size; int room; struct affix_rec **array; } *compos; struct affix_list_rec *concat; struct affix_list_rec *uni; } u; } *ex; int type; struct element_def_rec *lat_repr; } **array; } *display; struct member_list_rec { int size; int room; struct member_rec { int empty; int followlayout; char *first; int number; int sonnr; int tag; union { struct call_rec { char *nonterminal; struct pos_list_rec *display; struct rule_rec *def; } call; char *terminal; struct semiterminal_rec { struct cset_rec *set; struct pos_list_rec *display; } semi; } u; } **array; } *members; int number; int nodenr; int nrsons; struct affix_rec *locals; int empty; char *first; char *director; int rule_nr; } **array; } *alts; int kind; int empty; int lex; int ext; int number; int placeholder; int startswithlayout; int endsinlayout; char *first; char *follow; struct pos_list_rec *proto_display; int reachable; int has_sons; int goal; struct lextree_rec { char *remainder; struct lexend_list_rec { int size; int room; struct lexend_rec { int nodenr; struct int_list_rec *valuenrs; } **array; } *prods; struct lextree_list_rec { int size; int room; struct lextree_rec **array; } *tails; } *rev_tree; } *node; struct rule_tree_rec *left; struct rule_tree_rec *right; } **

user_defined_types: struct rule_tree_rec { struct rule_rec *node; struct rule_tree_rec *left; struct rule_tree_rec *right; }

user_defined_types: struct rule_rec { char *nonterminal; struct alt_list_rec *alts; int kind; int empty; int lex; int ext; int number; int placeholder; int startswithlayout; int endsinlayout; char *first; char *follow; struct pos_list_rec *proto_display; int reachable; int has_sons; int goal; struct lextree_rec *rev_tree; }

user_defined_types: struct alt_list_rec { int size; int room; struct alt_rec **array; }

user_defined_types: struct lextree_rec { char *remainder; struct lexend_list_rec *prods; struct lextree_list_rec *tails; }

user_defined_types: struct lexend_list_rec { int size; int room; struct lexend_rec **array; }

user_defined_types: struct alt_rec { struct pos_list_rec *display; struct member_list_rec *members; int number; int nodenr; int nrsons; struct affix_rec *locals; int empty; char *first; char *director; int rule_nr; }

user_defined_types: struct pos_list_rec { int size; int room; struct pos_rec **array; }

user_defined_types: struct pos_rec { int kind; struct expr_rec *ex; int type; struct element_def_rec *lat_repr; }

user_defined_types: struct variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec *def; }


decompiled_code:
const char **__fastcall lookup_syntax_rule(char *s1)
{
__int64 v1; // r12
const char **v2; // rbx
int v3; // eax

v1 = rule_root;
if ( !rule_root )
return (const char **)v1;
while ( 1 )
{
while ( 1 )
{
v2 = *(const char ***)v1;
v3 = strcmp(s1, **(const char ***)v1);
if ( v3 >= 0 )
break;
v1 = *(_QWORD *)(v1 + 8);
if ( !v1 )
return (const char **)v1;
}
if ( !v3 )
break;
v1 = *(_QWORD *)(v1 + 16);
if ( !v1 )
return (const char **)v1;
}
return v2;
}

canonical_decompiled_code:
const char **__fastcall func3(char *s1)
{
__int64 v1; // r12
const char **v2; // rbx
int v3; // eax

v1 = rule_root;
if ( !rule_root )
return (const char **)v1;
while ( 1 )
{
while ( 1 )
{
v2 = *(const char ***)v1;
v3 = strcmp(s1, **(const char ***)v1);
if ( v3 >= 0 )
break;
v1 = *(_QWORD *)(v1 + 8);
if ( !v1 )
return (const char **)v1;
}
if ( !v3 )
break;
v1 = *(_QWORD *)(v1 + 16);
if ( !v1 )
return (const char **)v1;
}
return v2;
}

original_code:
rule lookup_syntax_rule (string nont)
 { rule_tree ptr = rule_root;
   while (1)
      { int cond;
        if (ptr == ((rule_tree) ((void *)0))) return (((rule) ((void *)0)));
        cond = strcmp (nont, ptr -> node -> nonterminal);
        if (cond < 0) ptr = ptr -> left;
        else if (cond > 0) ptr = ptr -> right;
        else return (ptr -> node);
      };
 }

canonical_original_code:
struct rule_rec *lookup_syntax_rule(char *nont)
 { struct rule_tree_rec *ptr = rule_root;
   while (1)
      { int cond;
        if (ptr == ((rule_tree) ((void *)0))) return (((rule) ((void *)0)));
        cond = strcmp (nont, ptr -> node -> nonterminal);
        if (cond < 0) ptr = ptr -> left;
        else if (cond > 0) ptr = ptr -> right;
        else return (ptr -> node);
      };
 }

variable_types: struct rule_tree_rec { struct rule_rec { char *nonterminal; struct alt_list_rec { int size; int room; struct alt_rec { struct pos_list_rec { int size; int room; struct pos_rec { int kind; struct expr_rec { int tag; union { struct affix_rec { char *name; int type; struct affix_rec *next; struct value_rec { int admin_nr; int ref_count; void *dptr; int tag; union { char *str; int inum; double rnum; struct value_list_rec { int size; int room; struct value_rec **array; } *tuple; int slat; struct int_list_rec { int size; int room; int *array; } *elat; struct value_rec *free; } u; } *val; int ref_count; int reachable; int tag; union { struct variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec { char *nonterminal; struct meta_alt_list_rec { int size; int room; struct meta_alt_rec { struct expr_rec *e; int number; } **array; } *alts; int ext; int type; int kind; int empty; int number; struct value_rec *mvalue; int reachable; struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec { int number; struct element_def_list_rec { int size; int room; struct element_def_rec **array; } *defs; } *set; } *lat_repr; int needs_rec; int needs_recbup; } *def; } var; char *str; int inum; double rnum; struct cset_rec { int kind; char *str; } *semi; struct element_rec { char *eltnm; struct element_def_rec *def; } elt; struct expr_rec *cexpr; } u; } *single; struct affix_list_rec { int size; int room; struct affix_rec **array; } *compos; struct affix_list_rec *concat; struct affix_list_rec *uni; } u; } *ex; int type; struct element_def_rec *lat_repr; } **array; } *display; struct member_list_rec { int size; int room; struct member_rec { int empty; int followlayout; char *first; int number; int sonnr; int tag; union { struct call_rec { char *nonterminal; struct pos_list_rec *display; struct rule_rec *def; } call; char *terminal; struct semiterminal_rec { struct cset_rec *set; struct pos_list_rec *display; } semi; } u; } **array; } *members; int number; int nodenr; int nrsons; struct affix_rec *locals; int empty; char *first; char *director; int rule_nr; } **array; } *alts; int kind; int empty; int lex; int ext; int number; int placeholder; int startswithlayout; int endsinlayout; char *first; char *follow; struct pos_list_rec *proto_display; int reachable; int has_sons; int goal; struct lextree_rec { char *remainder; struct lexend_list_rec { int size; int room; struct lexend_rec { int nodenr; struct int_list_rec *valuenrs; } **array; } *prods; struct lextree_list_rec { int size; int room; struct lextree_rec **array; } *tails; } *rev_tree; } *node; struct rule_tree_rec *left; struct rule_tree_rec *right; } *

user_defined_types: struct member_list_rec { int size; int room; struct member_rec **array; }

user_defined_types: struct member_rec { int empty; int followlayout; char *first; int number; int sonnr; int tag; union { struct call_rec call; char *terminal; struct semiterminal_rec semi; } u; }

user_defined_types: struct expr_rec { int tag; union { struct affix_rec *single; struct affix_list_rec *compos; struct affix_list_rec *concat; struct affix_list_rec *uni; } u; }

user_defined_types: struct affix_rec { char *name; int type; struct affix_rec *next; struct value_rec *val; int ref_count; int reachable; int tag; union { struct variable_rec var; char *str; int inum; double rnum; struct cset_rec *semi; struct element_rec elt; struct expr_rec *cexpr; } u; }


decompiled_code:
int __fastcall enter_element(const char **a1)
{
const char ***v1; // rbx
const char *v2; // r12
__int64 *v3; // rbp
int result; // eax
const char ***v5; // rax

v1 = (const char ***)element_root;
if ( element_root )
{
v2 = *a1;
do
{
v3 = (__int64 *)(v1 + 1);
result = strcmp(v2, **v1);
if ( result >= 0 )
{
if ( !result )
return result;
v3 = (__int64 *)(v1 + 2);
}
v1 = (const char ***)*v3;
}
while ( *v3 );
}
else
{
v3 = &element_root;
}
v5 = (const char ***)ckmalloc(24LL);
*v3 = (__int64)v5;
*v5 = a1;
v5[1] = 0LL;
*(_QWORD *)(*v3 + 16) = 0LL;
return 1;
}

canonical_decompiled_code:
int __fastcall func4(const char **a1)
{
const char ***v1; // rbx
const char *v2; // r12
__int64 *v3; // rbp
int result; // eax
const char ***v5; // rax

v1 = (const char ***)element_root;
if ( element_root )
{
v2 = *a1;
do
{
v3 = (__int64 *)(v1 + 1);
result = strcmp(v2, **v1);
if ( result >= 0 )
{
if ( !result )
return result;
v3 = (__int64 *)(v1 + 2);
}
v1 = (const char ***)*v3;
}
while ( *v3 );
}
else
{
v3 = &element_root;
}
v5 = (const char ***)ckmalloc(24LL);
*v3 = (__int64)v5;
*v5 = a1;
v5[1] = 0LL;
*(_QWORD *)(*v3 + 16) = 0LL;
return 1;
}

original_code:
int enter_element (element_def node)
 { element_tree *ptr = &element_root;
   while (1)
      { int cond;
        if (*ptr == ((element_tree) ((void *)0)))
    { *ptr = (element_tree) ckmalloc
     (sizeof (struct element_tree_rec));
      (*ptr) -> node = node;
      (*ptr) -> left = ((element_tree) ((void *)0));
      (*ptr) -> right = ((element_tree) ((void *)0));
      return (1);
    };
        cond = strcmp (node -> eltnm, (*ptr) -> node -> eltnm);
        if (cond < 0) ptr = &((*ptr) -> left);
        else if (cond > 0) ptr = &((*ptr) -> right);
        else return (0);
      }
 }

canonical_original_code:
int enter_element(struct element_def_rec *node)
 { struct element_tree_rec **ptr = &element_root;
   while (1)
      { int cond;
        if (*ptr == ((element_tree) ((void *)0)))
    { *ptr = (struct element_tree_rec *) ckmalloc
     (sizeof (struct element_tree_rec));
      (*ptr) -> node = node;
      (*ptr) -> left = ((element_tree) ((void *)0));
      (*ptr) -> right = ((element_tree) ((void *)0));
      return (1);
    };
        cond = strcmp (node -> eltnm, (*ptr) -> node -> eltnm);
        if (cond < 0) ptr = &((*ptr) -> left);
        else if (cond > 0) ptr = &((*ptr) -> right);
        else return (0);
      }
 }

variable_types: struct element_tree_rec { struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec { int number; struct element_def_list_rec { int size; int room; struct element_def_rec **array; } *defs; } *set; } *node; struct element_tree_rec *left; struct element_tree_rec *right; } **

user_defined_types: struct element_tree_rec { struct element_def_rec *node; struct element_tree_rec *left; struct element_tree_rec *right; }

user_defined_types: struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec *set; }


decompiled_code:
const char **__fastcall lookup_element(char *s1)
{
__int64 v1; // r12
const char **v2; // rbx
int v3; // eax

v1 = element_root;
if ( !element_root )
return (const char **)v1;
while ( 1 )
{
while ( 1 )
{
v2 = *(const char ***)v1;
v3 = strcmp(s1, **(const char ***)v1);
if ( v3 >= 0 )
break;
v1 = *(_QWORD *)(v1 + 8);
if ( !v1 )
return (const char **)v1;
}
if ( !v3 )
break;
v1 = *(_QWORD *)(v1 + 16);
if ( !v1 )
return (const char **)v1;
}
return v2;
}

canonical_decompiled_code:
const char **__fastcall func5(char *s1)
{
__int64 v1; // r12
const char **v2; // rbx
int v3; // eax

v1 = element_root;
if ( !element_root )
return (const char **)v1;
while ( 1 )
{
while ( 1 )
{
v2 = *(const char ***)v1;
v3 = strcmp(s1, **(const char ***)v1);
if ( v3 >= 0 )
break;
v1 = *(_QWORD *)(v1 + 8);
if ( !v1 )
return (const char **)v1;
}
if ( !v3 )
break;
v1 = *(_QWORD *)(v1 + 16);
if ( !v1 )
return (const char **)v1;
}
return v2;
}

original_code:
element_def lookup_element (string eltnm)
 { element_tree ptr = element_root;
   while (1)
      { int cond;
        if (ptr == ((element_tree) ((void *)0))) return (((element_def) ((void *)0)));
        cond = strcmp (eltnm, ptr -> node -> eltnm);
        if (cond < 0) ptr = ptr -> left;
        else if (cond > 0) ptr = ptr -> right;
        else return (ptr -> node);
      };
 }

canonical_original_code:
struct element_def_rec *lookup_element(char *eltnm)
 { struct element_tree_rec *ptr = element_root;
   while (1)
      { int cond;
        if (ptr == ((element_tree) ((void *)0))) return (((element_def) ((void *)0)));
        cond = strcmp (eltnm, ptr -> node -> eltnm);
        if (cond < 0) ptr = ptr -> left;
        else if (cond > 0) ptr = ptr -> right;
        else return (ptr -> node);
      };
 }

variable_types:
eltnm
char *

variable_types: struct element_tree_rec { struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec { int number; struct element_def_list_rec { int size; int room; struct element_def_rec **array; } *defs; } *set; } *node; struct element_tree_rec *left; struct element_tree_rec *right; } *

user_defined_types: struct element_set_rec { int number; struct element_def_list_rec *defs; }


decompiled_code:
void init_tree()
{
rule_root = 0LL;
meta_root = 0LL;
element_root = 0LL;
}

canonical_decompiled_code:
void func6()
{
rule_root = 0LL;
meta_root = 0LL;
element_root = 0LL;
}

original_code:
void init_tree ()
 { rule_root = ((rule_tree) ((void *)0));
   meta_root = ((meta_tree) ((void *)0));
   element_root = ((element_tree) ((void *)0));
 }

canonical_original_code:
void init_tree()
 { rule_root = ((rule_tree) ((void *)0));
   meta_root = ((meta_tree) ((void *)0));
   element_root = ((element_tree) ((void *)0));
 }


decompiled_code:
__int64 __fastcall generate_meta_rule_declaration(const char **a1)
{
const char *v1; // rsi
__int64 result; // rax

if ( *((_DWORD *)a1 + 12) )
{
v1 = *a1;
if ( *((_DWORD *)a1 + 4) )
{
code_line("affix_node make_%s_affix ();", v1);
return code_line("void rec_%s_value ();", *a1);
}
code_line("static affix_node make_%s_affix ();", v1);
if ( !*((_DWORD *)a1 + 16) )
{
result = *((unsigned int *)a1 + 17);
if ( !(_DWORD)result )
return result;
return code_line("static void recbup_%s_value ();", *a1);
}
code_line("static void rec_%s_value ();", *a1);
result = *((unsigned int *)a1 + 17);
if ( (_DWORD)result )
return code_line("static void recbup_%s_value ();", *a1);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(const char **a1)
{
const char *v1; // rsi
__int64 result; // rax

if ( *((_DWORD *)a1 + 12) )
{
v1 = *a1;
if ( *((_DWORD *)a1 + 4) )
{
code_line("affix_node make_%s_affix ();", v1);
return code_line("void rec_%s_value ();", *a1);
}
code_line("static affix_node make_%s_affix ();", v1);
if ( !*((_DWORD *)a1 + 16) )
{
result = *((unsigned int *)a1 + 17);
if ( !(_DWORD)result )
return result;
return code_line("static void recbup_%s_value ();", *a1);
}
code_line("static void rec_%s_value ();", *a1);
result = *((unsigned int *)a1 + 17);
if ( (_DWORD)result )
return code_line("static void recbup_%s_value ();", *a1);
}
return result;
}

original_code:
static void generate_meta_rule_declaration (meta_rule mrule)
 { if (!mrule -> reachable) return;
   if (mrule -> ext)
      { code_line ("affix_node make_%s_affix ();", mrule -> nonterminal);
        code_line ("void rec_%s_value ();", mrule -> nonterminal);
        return;
      };
          code_line ("static affix_node make_%s_affix ();", mrule -> nonterminal);
   if (mrule -> needs_rec)
      code_line ("static void rec_%s_value ();", mrule -> nonterminal);
   if (mrule -> needs_recbup)
      code_line ("static void recbup_%s_value ();", mrule -> nonterminal);
 }

canonical_original_code:
static void generate_meta_rule_declaration(struct meta_rule_rec *mrule)
 { if (!mrule -> reachable) return;
   if (mrule -> ext)
      { code_line ("affix_node make_%s_affix ();", mrule -> nonterminal);
        code_line ("void rec_%s_value ();", mrule -> nonterminal);
        return;
      };
          code_line ("static affix_node make_%s_affix ();", mrule -> nonterminal);
   if (mrule -> needs_rec)
      code_line ("static void rec_%s_value ();", mrule -> nonterminal);
   if (mrule -> needs_recbup)
      code_line ("static void recbup_%s_value ();", mrule -> nonterminal);
 }

variable_types: struct meta_rule_rec { char *nonterminal; struct meta_alt_list_rec { int size; int room; struct meta_alt_rec { struct expr_rec { int tag; union { struct affix_rec { char *name; int type; struct affix_rec *next; struct value_rec { int admin_nr; int ref_count; void *dptr; int tag; union { char *str; int inum; double rnum; struct value_list_rec { int size; int room; struct value_rec **array; } *tuple; int slat; struct int_list_rec { int size; int room; int *array; } *elat; struct value_rec *free; } u; } *val; int ref_count; int reachable; int tag; union { struct variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec *def; } var; char *str; int inum; double rnum; struct cset_rec { int kind; char *str; } *semi; struct element_rec { char *eltnm; struct element_def_rec { char *eltnm; int number; int eltnr; struct element_set_rec { int number; struct element_def_list_rec { int size; int room; struct element_def_rec **array; } *defs; } *set; } *def; } elt; struct expr_rec *cexpr; } u; } *single; struct affix_list_rec { int size; int room; struct affix_rec **array; } *compos; struct affix_list_rec *concat; struct affix_list_rec *uni; } u; } *e; int number; } **array; } *alts; int ext; int type; int kind; int empty; int number; struct value_rec *mvalue; int reachable; struct element_def_rec *lat_repr; int needs_rec; int needs_recbup; } *

user_defined_types: struct meta_rule_rec { char *nonterminal; struct meta_alt_list_rec *alts; int ext; int type; int kind; int empty; int number; struct value_rec *mvalue; int reachable; struct element_def_rec *lat_repr; int needs_rec; int needs_recbup; }

user_defined_types: struct meta_alt_list_rec { int size; int room; struct meta_alt_rec **array; }

user_defined_types: struct meta_alt_rec { struct expr_rec *e; int number; }

user_defined_types: struct value_rec { int admin_nr; int ref_count; void *dptr; int tag; union { char *str; int inum; double rnum; struct value_list_rec *tuple; int slat; struct int_list_rec *elat; struct value_rec *free; } u; }

user_defined_types: struct element_rec { char *eltnm; struct element_def_rec *def; }


decompiled_code:
__int64 generate_meta_rule_declarations()
{
__int64 v0; // rbx
const char **v1; // rdi

code_line("/* forward declare meta rule routines */");
if ( nr_of_meta_rules > 0 )
{
v0 = 0LL;
do
{
v1 = *(const char ***)(all_meta_rules + 8 * v0++);
generate_meta_rule_declaration(v1);
}
while ( nr_of_meta_rules > (int)v0 );
}
return code_line((const char *)&unk_DC2);
}

canonical_decompiled_code:
__int64 func1()
{
__int64 v0; // rbx
const char **v1; // rdi

code_line("/* forward declare meta rule routines */");
if ( nr_of_meta_rules > 0 )
{
v0 = 0LL;
do
{
v1 = *(const char ***)(all_meta_rules + 8 * v0++);
func0(v1);
}
while ( nr_of_meta_rules > (int)v0 );
}
return code_line((const char *)&unk_DC2);
}

original_code:
static void generate_meta_rule_declarations ()
 { int ix;
   code_line ("/* forward declare meta rule routines */");
   for (ix = 0; ix < nr_of_meta_rules; ix++)
      generate_meta_rule_declaration (all_meta_rules[ix]);
   code_line ("");
 }

canonical_original_code:
static void generate_meta_rule_declarations()
 { int ix;
   code_line ("/* forward declare meta rule routines */");
   for (ix = 0; ix < nr_of_meta_rules; ix++)
      generate_meta_rule_declaration (all_meta_rules[ix]);
   code_line ("");
 }

variable_types: ix int


decompiled_code:
__int64 __fastcall generate_qstack_mcheck(const char **a1, int a2, int a3)
{
const char *v4; // rsi
const char *v5; // r8

if ( a3 )
{
code_line("\t %sif (lqptr != qptr)", (const char *)&unk_DC2);
v4 = (const char *)&unk_DC2;
v5 = "body";
}
else
{
code_line("\t %sif (lqptr != qptr)", " ");
v4 = " ";
v5 = (const char *)&unk_DC2;
}
return code_line(
"\t %s panic (\"qstack inconsistency detected in metarule %s, alt %d, rec%s\");",
v4,
*a1,
(unsigned int)(a2 + 1),
v5);
}

canonical_decompiled_code:
__int64 __fastcall func2(const char **a1, int a2, int a3)
{
const char *v4; // rsi
const char *v5; // r8

if ( a3 )
{
code_line("\t %sif (lqptr != qptr)", (const char *)&unk_DC2);
v4 = (const char *)&unk_DC2;
v5 = "body";
}
else
{
code_line("\t %sif (lqptr != qptr)", " ");
v4 = " ";
v5 = (const char *)&unk_DC2;
}
return code_line(
"\t %s panic (\"qstack inconsistency detected in metarule %s, alt %d, rec%s\");",
v4,
*a1,
(unsigned int)(a2 + 1),
v5);
}

original_code:
static void generate_qstack_mcheck (meta_rule mrule, int i, int body)
 { char *indent = (body)?"":"     ";
   code_line ("\t   %sif (lqptr != qptr)", indent);
   code_line ("\t   %s   panic (\"qstack inconsistency detected in metarule %s, alt %d, rec%s\");",
  indent, mrule -> nonterminal, i+1, (body)?"body":"");
 }

canonical_original_code:
static void generate_qstack_mcheck(struct meta_rule_rec *mrule, int i, int body)
 { char *indent = (body)?"":"     ";
   code_line ("\t   %sif (lqptr != qptr)", indent);
   code_line ("\t   %s   panic (\"qstack inconsistency detected in metarule %s, alt %d, rec%s\");",
  indent, mrule -> nonterminal, i+1, (body)?"body":"");
 }

variable_types: i int

variable_types: body int

variable_types:
indent
char *

user_defined_types: struct affix_list_rec { int size; int room; struct affix_rec **array; }

user_defined_types: struct cset_rec { int kind; char *str; }

user_defined_types: struct value_list_rec { int size; int room; struct value_rec **array; }

user_defined_types: struct int_list_rec { int size; int room; int *array; }

user_defined_types: struct element_def_list_rec { int size; int room; struct element_def_rec **array; }


decompiled_code:
void __fastcall generate_creator_rule(const char **a1)
{
unsigned int v1; // eax

if ( !*((_DWORD *)a1 + 4) && *((_DWORD *)a1 + 12) )
{
reset_temporaries();
code_line("static affix_node make_%s_affix ()", *a1);
if ( a1[5] )
{
code_line("\t{");
v1 = generate_temp_value(a1[5], 0LL);
code_line("\t return (value_to_affix (\"meta_%s\", v%d));", *a1, v1);
}
else
{
code_line("\t{ affix_node new = new_affix_node (\"meta_%s\");", *a1);
code_line("\t new -> mfunc = rec_%s_value;", *a1);
code_line("\t return (new);");
}
code_line("\t};\n");
}
}

canonical_decompiled_code:
void __fastcall func3(const char **a1)
{
unsigned int v1; // eax

if ( !*((_DWORD *)a1 + 4) && *((_DWORD *)a1 + 12) )
{
reset_temporaries();
code_line("static affix_node make_%s_affix ()", *a1);
if ( a1[5] )
{
code_line("\t{");
v1 = generate_temp_value(a1[5], 0LL);
code_line("\t return (value_to_affix (\"meta_%s\", v%d));", *a1, v1);
}
else
{
code_line("\t{ affix_node new = new_affix_node (\"meta_%s\");", *a1);
code_line("\t new -> mfunc = rec_%s_value;", *a1);
code_line("\t return (new);");
}
code_line("\t};\n");
}
}

original_code:
static void generate_creator_rule (meta_rule mrule)
 { if (mrule -> ext) return;
   if (!mrule -> reachable) return;
   reset_temporaries ();
   code_line ("static affix_node make_%s_affix ()", mrule -> nonterminal);
   if (mrule -> mvalue != ((value) ((void *)0)))
      { int valnr;
        code_line ("\t{");
        valnr = generate_temp_value (mrule -> mvalue, 0);
        code_line ("\t  return (value_to_affix (\"meta_%s\", v%d));",
     mrule -> nonterminal, valnr);
        code_line ("\t};\n");
        return;
      };
   code_line ("\t{ affix_node new = new_affix_node (\"meta_%s\");",
     mrule -> nonterminal);
   code_line ("\t  new -> mfunc = rec_%s_value;", mrule -> nonterminal);
   code_line ("\t  return (new);");
   code_line ("\t};\n");
 }

canonical_original_code:
static void generate_creator_rule(struct meta_rule_rec *mrule)
 { if (mrule -> ext) return;
   if (!mrule -> reachable) return;
   reset_temporaries ();
   code_line ("static affix_node make_%s_affix ()", mrule -> nonterminal);
   if (mrule -> mvalue != ((value) ((void *)0)))
      { int valnr;
        code_line ("\t{");
        valnr = generate_temp_value (mrule -> mvalue, 0);
        code_line ("\t  return (value_to_affix (\"meta_%s\", v%d));",
     mrule -> nonterminal, valnr);
        code_line ("\t};\n");
        return;
      };
   code_line ("\t{ affix_node new = new_affix_node (\"meta_%s\");",
     mrule -> nonterminal);
   code_line ("\t  new -> mfunc = rec_%s_value;", mrule -> nonterminal);
   code_line ("\t  return (new);");
   code_line ("\t};\n");
 }

variable_types: valnr int

user_defined_types: struct variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec *def; }


decompiled_code:
void generate_creator_rules()
{
__int64 v0; // rbx
const char **v1; // rdi

if ( nr_of_meta_rules > 0 )
{
v0 = 0LL;
do
{
v1 = *(const char ***)(all_meta_rules + 8 * v0++);
generate_creator_rule(v1);
}
while ( nr_of_meta_rules > (int)v0 );
}
}

canonical_decompiled_code:
void func4()
{
__int64 v0; // rbx
const char **v1; // rdi

if ( nr_of_meta_rules > 0 )
{
v0 = 0LL;
do
{
v1 = *(const char ***)(all_meta_rules + 8 * v0++);
func3(v1);
}
while ( nr_of_meta_rules > (int)v0 );
}
}

original_code:
static void generate_creator_rules ()
 { int ix;
   for (ix = 0; ix < nr_of_meta_rules; ix++)
      generate_creator_rule (all_meta_rules[ix]);
 }

canonical_original_code:
static void generate_creator_rules()
 { int ix;
   for (ix = 0; ix < nr_of_meta_rules; ix++)
      generate_creator_rule (all_meta_rules[ix]);
 }