decompiled_code:
void __fastcall myset_free(__int64 a1)
{
myset_clear(a1);
free(*(void **)(a1 + 8));
}

canonical_decompiled_code:
void __fastcall func14(__int64 a1)
{
func13(a1);
free(*(void **)(a1 + 8));
}

original_code:
void myset_free(myset *s)
{
 myset_clear(s);
 free(s->buckets);
}

canonical_original_code:
void myset_free(struct myset *s)
{
 myset_clear(s);
 free(s->buckets);
}


decompiled_code:
__int64 __fastcall edge_cmp(const void *a1, const void *a2)
{
return (unsigned int)(*(_DWORD *)(*(_QWORD *)a1 + 4LL) - *(_DWORD *)(*(_QWORD *)a2 + 4LL));
}

canonical_decompiled_code:
__int64 __fastcall func15(const void *a1, const void *a2)
{
return (unsigned int)(*(_DWORD *)(*(_QWORD *)a1 + 4LL) - *(_DWORD *)(*(_QWORD *)a2 + 4LL));
}

original_code:
int edge_cmp(const void *a, const void *b)
{
 return (*(edge**)a)->weight - (*(edge**)b)->weight;
}

canonical_original_code:
int edge_cmp(void *a, void *b)
{
 return (*(struct edge **)a)->weight - (*(struct edge **)b)->weight;
}

variable_types:
a
void *

variable_types:
b
void *

return_type: int

user_defined_types: struct edge { char start; char end; int weight; }


hash

decompiled_code:
__int64 __fastcall hash(char *a1)
{
return (unsigned int)*a1;
}

canonical_decompiled_code:
__int64 __fastcall func16(char *a1)
{
return (unsigned int)*a1;
}

original_code:
int hash(const void *a)
{
 return *(char*)a;
}

canonical_original_code:
int hash(void *a)
{
 return *(char *)a;
}


cmp

decompiled_code:
__int64 __fastcall cmp(char *a1, char *a2)
{
return (unsigned int)(*a1 - *a2);
}

canonical_decompiled_code:
__int64 __fastcall func17(char *a1, char *a2)
{
return (unsigned int)(*a1 - *a2);
}

original_code:
int cmp(const void *a, const void *b)
{
 return *(char*)a - *(char*)b;
}

canonical_original_code:
int cmp(void *a, void *b)
{
 return *(char *)a - *(char *)b;
}


decompiled_code:
void __fastcall mylist_free(void *a1)
{
free(a1);
}

canonical_decompiled_code:
void __fastcall func7(void *a1)
{
free(a1);
}

original_code:
void mylist_free(mylist *l)
{
 free(l);
}

canonical_original_code:
void mylist_free(struct _list *l)
{
 free(l);
}

variable_types: struct _list { void *data; struct _list *next; } *

return_type: void


decompiled_code:
__int64 __fastcall mybtree_free(__int64 a1)
{
if ( a1 )
{
mybtree_free(*(_QWORD *)(a1 + 8));
mybtree_free(*(_QWORD *)(a1 + 16));
}
return 0LL;
}

original_code:
int mybtree_free(mybtree *root)
{
 if(root == ((void *)0))
  return 0;
 mybtree_free(root->left);
 mybtree_free(root->right);
 return 0;
}

canonical_original_code:
int mybtree_free(struct _mybtree *root)
{
 if(root == ((void *)0))
  return 0;
 mybtree_free(root->left);
 mybtree_free(root->right);
 return 0;
}

variable_types: struct _mybtree { void *value; struct _mybtree *left; struct _mybtree *right; } *


original_code:
mybtree* huffman_tree(frequency **f, int len, int (*compare_fun)(void*, void*))
{
 int i = 0;
 mybtree **heap = (mybtree**)malloc(len * sizeof(mybtree*));
 for(i = 0; i < len; i++)
  heap[i] = mybtree_new(f[i]);
 int son = 0;
 int parent = 0;
 mybtree *temp;
 for(i = 0; i < len; i++){
  son = i;
  parent = (son - 1) / 2;
  while(parent >= 0 && compare_fun(heap[son]->value, heap[parent]->value) < 0){
   { temp = heap[son]; heap[son] = heap[parent]; heap[parent] = temp; };
   son = parent;
   parent = (son - 1) / 2;
  }
 }
 mybtree *root = heap[0];
 frequency *fre;
 son = 1;
 parent = 0;
 while(len > 1){
  fre = (frequency*)malloc(sizeof(frequency));
  fre->symbol = ((void *)0);
  fre->weight = 0;
  root = mybtree_new(fre);
  for(i = 0; i < 2; i++){
   { temp = heap[0]; heap[0] = heap[len - 1]; heap[len - 1] = temp; };
   len--;
   if(i == 0)
    root->right = heap[len];
   else
    root->left = heap[len];
   fre->weight += ((frequency*)heap[len]->value)->weight;
   parent = 0;
   son = parent * 2 + 1;
   while(son < len){
    if(son < len - 1 && compare_fun(heap[son]->value, heap[son + 1]->value) > 0)
     son++;
    if(compare_fun(heap[parent]->value, heap[son]->value) < 0)
     break;
    { temp = heap[parent]; heap[parent] = heap[son]; heap[son] = temp; };
    parent = son;
    son = parent * 2 + 1;
   }
  }
  heap[len] = root;
  len++;
  son = len - 1;
  parent = (son - 1) / 2;
  while(parent >= 0 && compare_fun(heap[son]->value, heap[parent]->value) < 0){
   { temp = heap[son]; heap[son] = heap[parent]; heap[parent] = temp; };
   son = parent;
   parent = (son - 1) / 2;
  }
 }
 root = heap[0];
 free(heap);
 return root;
}

canonical_original_code:
struct _mybtree *huffman_tree(struct frequency **f, int len, int (*compare_fun)(void *, void *))
{
 int i = 0;
 struct _mybtree **heap = (mybtree**)malloc(len * sizeof(mybtree*));
 for(i = 0; i < len; i++)
  heap[i] = mybtree_new(f[i]);
 int son = 0;
 int parent = 0;
 struct _mybtree *temp;
 for(i = 0; i < len; i++){
  son = i;
  parent = (son - 1) / 2;
  while(parent >= 0 && compare_fun(heap[son]->value, heap[parent]->value) < 0){
   { temp = heap[son]; heap[son] = heap[parent]; heap[parent] = temp; };
   son = parent;
   parent = (son - 1) / 2;
  }
 }
 struct _mybtree *root = heap[0];
 struct frequency *fre;
 son = 1;
 parent = 0;
 while(len > 1){
  fre = (struct frequency *)malloc(sizeof(frequency));
  fre->symbol = ((void *)0);
  fre->weight = 0;
  root = mybtree_new(fre);
  for(i = 0; i < 2; i++){
   { temp = heap[0]; heap[0] = heap[len - 1]; heap[len - 1] = temp; };
   len--;
   if(i == 0)
    root->right = heap[len];
   else
    root->left = heap[len];
   fre->weight += ((struct frequency *)heap[len]->value)->weight;
   parent = 0;
   son = parent * 2 + 1;
   while(son < len){
    if(son < len - 1 && compare_fun(heap[son]->value, heap[son + 1]->value) > 0)
     son++;
    if(compare_fun(heap[parent]->value, heap[son]->value) < 0)
     break;
    { temp = heap[parent]; heap[parent] = heap[son]; heap[son] = temp; };
    parent = son;
    son = parent * 2 + 1;
   }
  }
  heap[len] = root;
  len++;
  son = len - 1;
  parent = (son - 1) / 2;
  while(parent >= 0 && compare_fun(heap[son]->value, heap[parent]->value) < 0){
   { temp = heap[son]; heap[son] = heap[parent]; heap[parent] = temp; };
   son = parent;
   parent = (son - 1) / 2;
  }
 }
 root = heap[0];
 free(heap);
 return root;
}

variable_types: struct frequency { void *symbol; int weight; } **

variable_types: len int

variable_types: i int

variable_types: struct _mybtree { void *value; struct _mybtree *left; struct _mybtree *right; } **

variable_types: son int

variable_types: parent int


decompiled_code:
__int64 __fastcall search_symbol(__int64 a1, char a2, _BYTE *a3)
{
char *v4; // rax
char v5; // al
__int64 result; // rax
_BYTE *v7; // r13

if ( !a1 )
return 0LL;
v4 = **(char ***)a1;
if ( v4 )
{
v5 = *v4;
*a3 = 0;
result = v5 == a2;
}
else
{
v7 = a3 + 1;
if ( (unsigned int)search_symbol(*(_QWORD *)(a1 + 8), (unsigned int)a2, a3 + 1) )
{
*a3 = 48;
result = 1LL;
}
else
{
result = search_symbol(*(_QWORD *)(a1 + 16), (unsigned int)a2, v7);
if ( (_DWORD)result )
{
*a3 = 49;
result = 1LL;
}
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1, char a2, _BYTE *a3)
{
char *v4; // rax
char v5; // al
__int64 result; // rax
_BYTE *v7; // r13

if ( !a1 )
return 0LL;
v4 = **(char ***)a1;
if ( v4 )
{
v5 = *v4;
*a3 = 0;
result = v5 == a2;
}
else
{
v7 = a3 + 1;
if ( (unsigned int)func10(*(_QWORD *)(a1 + 8), (unsigned int)a2, a3 + 1) )
{
*a3 = 48;
result = 1LL;
}
else
{
result = func10(*(_QWORD *)(a1 + 16), (unsigned int)a2, v7);
if ( (_DWORD)result )
{
*a3 = 49;
result = 1LL;
}
}
}
return result;
}

original_code:
int search_symbol(mybtree *huff, char c, char *s)
{
 if(huff == ((void *)0))
  return 0;
 frequency *f = huff->value;
 if(f->symbol == ((void *)0)){
  if(search_symbol(huff->left, c, s + 1))
   *s = '0';
  else if(search_symbol(huff->right, c, s + 1))
   *s = '1';
  else
   return 0;
  return 1;
 }
 char val = *(char*)f->symbol;
 *s = '\0';
 return (val == c);
}

canonical_original_code:
int search_symbol(struct _mybtree *huff, char c, char *s)
{
 if(huff == ((void *)0))
  return 0;
 struct frequency *f = huff->value;
 if(f->symbol == ((void *)0)){
  if(search_symbol(huff->left, c, s + 1))
   *s = '0';
  else if(search_symbol(huff->right, c, s + 1))
   *s = '1';
  else
   return 0;
  return 1;
 }
 char val = *(char*)f->symbol;
 *s = '\0';
 return (val == c);
}

variable_types: c char

variable_types:
s
char *

variable_types: struct frequency { void *symbol; int weight; } *

variable_types: val char

user_defined_types: struct _mybtree { void *value; struct _mybtree *left; struct _mybtree *right; }


compare

decompiled_code:
__int64 __fastcall compare(__int64 a1, __int64 a2)
{
return (unsigned int)(*(_DWORD *)(a1 + 8) - *(_DWORD *)(a2 + 8));
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1, __int64 a2)
{
return (unsigned int)(*(_DWORD *)(a1 + 8) - *(_DWORD *)(a2 + 8));
}

original_code:
int compare(void *a, void *b)
{
 return (((frequency*)a)->weight - ((frequency*)b)->weight);
}

canonical_original_code:
int compare(void *a, void *b)
{
 return (((struct frequency *)a)->weight - ((struct frequency *)b)->weight);
}

user_defined_types: struct frequency { void *symbol; int weight; }


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
void *v3; // rbp
const char *v4; // r14
char *v5; // rbp
int v7; // [rsp+4h] [rbp-444h]
int v8; // [rsp+8h] [rbp-440h]
char s[1064]; // [rsp+20h] [rbp-428h] BYREF

puts("input how many symbol");
__isoc99_scanf();
malloc(1uLL);
v3 = malloc(0LL);
puts("input the string need to encode");
__isoc99_scanf();
v8 = strlen(s);
huffman_tree((__int64)v3, 0, (int (__fastcall *)(_QWORD, _QWORD))compare);
malloc(0LL);
v7 = (int)(log2((double)0) + 2.0);
v4 = (const char *)malloc(v8 * v7);
if ( v8 > 0 )
{
v5 = s;
do
++v5;
while ( v5 != &s[v8 - 1 + 1] );
}
printf("%s: %s\n", s, v4);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
void *v3; // rbp
const char *v4; // r14
char *v5; // rbp
int v7; // [rsp+4h] [rbp-444h]
int v8; // [rsp+8h] [rbp-440h]
char s[1064]; // [rsp+20h] [rbp-428h] BYREF

puts("input how many symbol");
__isoc99_scanf();
malloc(1uLL);
v3 = malloc(0LL);
puts("input the string need to encode");
__isoc99_scanf();
v8 = strlen(s);
func9((__int64)v3, 0, (int (__fastcall *)(_QWORD, _QWORD))compare);
malloc(0LL);
v7 = (int)(log2((double)0) + 2.0);
v4 = (const char *)malloc(v8 * v7);
if ( v8 > 0 )
{
v5 = s;
do
++v5;
while ( v5 != &s[v8 - 1 + 1] );
}
printf("%s: %s\n", s, v4);
return 0;
}

original_code:
int main(){
 char s[1000];
 int len = 0;
 printf("input how many symbol\n");
 scanf("%d", &len);
 char *sym = (char*)malloc((len + 1) * sizeof(char));
 frequency **f = (frequency**)malloc(len * sizeof(frequency*));
 int i = 0, j = 0;
 for(i = 0; i < len; i++){
  f[i] = (frequency*)malloc(sizeof(frequency));
  scanf("%s %d", &sym[i], &f[i]->weight);
  f[i]->symbol = &sym[i];
 }
 printf("input the string need to encode\n");
 scanf("%s", s);
 int slen = strlen(s);
 mybtree *huffman = huffman_tree(f, len, compare);
 char **table = (char**)malloc(len * sizeof(char*));
 int l = log2(len) + 2;
 for(i = 0; i < len; i++){
  table[i] = (char*)malloc(l * sizeof(char));
  search_symbol(huffman, sym[i], table[i]);
  printf("%c: %s\n", sym[i], table[i]);
 }
 char *encode = (char*)malloc(l * slen * sizeof(char));
 char *ptr = encode;
 for(i = 0; i < slen; i++){
  for(j = 0; j < len; j++){
   if(s[i] == sym[j]){
    ptr += sprintf(ptr, table[j]);
    break;
   }
  }
 }
 printf("%s: %s\n", s, encode);
 return 0;
}

canonical_original_code:
int main(){
 char s[1000];
 int len = 0;
 printf("input how many symbol\n");
 scanf("%d", &len);
 char *sym = (char*)malloc((len + 1) * sizeof(char));
 struct frequency **f = (frequency**)malloc(len * sizeof(frequency*));
 int i = 0; int j = 0;
 for(i = 0; i < len; i++){
  f[i] = (struct frequency *)malloc(sizeof(frequency));
  scanf("%s %d", &sym[i], &f[i]->weight);
  f[i]->symbol = &sym[i];
 }
 printf("input the string need to encode\n");
 scanf("%s", s);
 int slen = strlen(s);
 struct _mybtree *huffman = huffman_tree(f, len, compare);
 char **table = (char**)malloc(len * sizeof(char*));
 int l = log2(len) + 2;
 for(i = 0; i < len; i++){
  table[i] = (char *)malloc(l * sizeof(char));
  search_symbol(huffman, sym[i], table[i]);
  printf("%c: %s\n", sym[i], table[i]);
 }
 char *encode = (char*)malloc(l * slen * sizeof(char));
 char *ptr = encode;
 for(i = 0; i < slen; i++){
  for(j = 0; j < len; j++){
   if(s[i] == sym[j]){
    ptr += sprintf(ptr, table[j]);
    break;
   }
  }
 }
 printf("%s: %s\n", s, encode);
 return 0;
}

variable_types:
sym
char *

variable_types: j int

variable_types: slen int

variable_types:
table
char **

variable_types: l int

variable_types:
encode
char *

variable_types:
ptr
char *


original_code:
int mystack_push(mystack *s, void *val)
{
 mylist *list;
 int pos = s->length % s->size;
 if(pos == 0){
  list = mylist_new(s->size);
  list->next = s->head;
  s->head = list;
 }
 list = s->head;
 list->value[pos] = val;
 s->length++;
 return 0;
}

canonical_original_code:
int mystack_push(struct mystack *s, void *val)
{
 struct _list *list;
 int pos = s->length % s->size;
 if(pos == 0){
  list = mylist_new(s->size);
  list->next = s->head;
  s->head = list;
 }
 list = s->head;
 list->value[pos] = val;
 s->length++;
 return 0;
}

variable_types: struct mystack { int length; int size; struct _list { void **value; struct _list *next; } *head; } *

variable_types:
val
void *

variable_types: pos int

user_defined_types: struct mystack { int length; int size; struct _list *head; }


original_code:
void* mystack_pop(mystack *s)
{
 if(s->length == 0)
  return ((void *)0);
 s->length--;
 mylist *list = s->head;
 int pos = s->length % s->size;
 void *rtn = list->value[pos];
 list->value[pos] = ((void *)0);
 if(pos == 0){
  s->head = list->next;
  mylist_free(list);
 }
 return rtn;
}

canonical_original_code:
void *mystack_pop(struct mystack *s)
{
 if(s->length == 0)
  return ((void *)0);
 s->length--;
 struct _list *list = s->head;
 int pos = s->length % s->size;
 void *rtn = list->value[pos];
 list->value[pos] = ((void *)0);
 if(pos == 0){
  s->head = list->next;
  mylist_free(list);
 }
 return rtn;
}

variable_types: struct _list { void **value; struct _list *next; } *

variable_types:
rtn
void *

return_type: void *


decompiled_code:
__int64 __fastcall mystack_top(__int64 a1)
{
__int64 result; // rax

if ( *(_DWORD *)a1 )
result = *(_QWORD *)(**(_QWORD **)(a1 + 8) + 8LL * ((*(_DWORD *)a1 - 1) % *(_DWORD *)(a1 + 4)));
else
result = 0LL;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1)
{
__int64 result; // rax

if ( *(_DWORD *)a1 )
result = *(_QWORD *)(**(_QWORD **)(a1 + 8) + 8LL * ((*(_DWORD *)a1 - 1) % *(_DWORD *)(a1 + 4)));
else
result = 0LL;
return result;
}

original_code:
void* mystack_top(mystack *s)
{
 if(s->length == 0)
  return ((void *)0);
 mylist *list = s->head;
 int pos = (s->length - 1) % s->size;
 return list->value[pos];
}

canonical_original_code:
void *mystack_top(struct mystack *s)
{
 if(s->length == 0)
  return ((void *)0);
 struct _list *list = s->head;
 int pos = (s->length - 1) % s->size;
 return list->value[pos];
}

user_defined_types: struct _list { void **value; struct _list *next; }


decompiled_code:
_BOOL8 __fastcall mystack_empty(_DWORD *a1)
{
return *a1 == 0;
}

canonical_decompiled_code:
_BOOL8 __fastcall func11(_DWORD *a1)
{
return *a1 == 0;
}

original_code:
int mystack_empty(mystack *s)
{
 return s->length == 0;
}

canonical_original_code:
int mystack_empty(struct mystack *s)
{
 return s->length == 0;
}


decompiled_code:
__int64 __fastcall mystack_flush(__int64 a1)
{
_QWORD *i; // rdi

for ( i = *(_QWORD **)(a1 + 8); i; i = *(_QWORD **)(a1 + 8) )
{
*(_QWORD *)(a1 + 8) = i[1];
mylist_free(i);
}
return 0LL;
}

original_code:
int mystack_flush(mystack *s)
{
 mylist *list;
 while(s->head != ((void *)0)){
  list = s->head;
  s->head = s->head->next;
  mylist_free(list);
 }
 return 0;
}

canonical_original_code:
int mystack_flush(struct mystack *s)
{
 struct _list *list;
 while(s->head != ((void *)0)){
  list = s->head;
  s->head = s->head->next;
  mylist_free(list);
 }
 return 0;
}


decompiled_code:
__int64 __fastcall mystack_free(void *ptr)
{
mystack_flush((__int64)ptr);
free(ptr);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func13(void *ptr)
{
func12((__int64)ptr);
free(ptr);
return 0LL;
}

original_code:
int mystack_free(mystack *s)
{
 mystack_flush(s);
 free(s);
 return 0;
}

canonical_original_code:
int mystack_free(struct mystack *s)
{
 mystack_flush(s);
 free(s);
 return 0;
}


priority

decompiled_code:
__int64 __fastcall priority(char a1)
{
__int64 result; // rax

switch ( a1 )
{
case '(':
result = 0LL;
break;
case '*':
case '/':
result = 3LL;
break;
case '+':
case '-':
result = 2LL;
break;
default:
return result;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func14(char a1)
{
__int64 result; // rax

switch ( a1 )
{
case '(':
result = 0LL;
break;
case '*':
case '/':
result = 3LL;
break;
case '+':
case '-':
result = 2LL;
break;
default:
return result;
}
return result;
}

original_code:
int priority(char a)
{
 switch(a){
  case '*':
  case '/':
   return 3;
  case '+':
  case '-':
   return 2;
  case '(':
   return 0;
 }
}

variable_types: a char


decompiled_code:
void __fastcall combine_rule(char a1, char a2)
{
char v2; // cl
__int64 v3; // rax

v2 = a1 - 40;
if ( (unsigned __int8)(a1 - 40) <= 0x36u )
{
if ( ((1LL << v2) & 0xAD) != 0 )
{
priority(a1);
priority(a2);
}
else
{
v3 = 1LL << v2;
if ( _bittest64(&v3, 0x36u) )
{
priority(94);
priority(a2);
}
}
}
}

original_code:
int combine_rule(char a, char b)
{
 switch(a){
  case '+':
  case '-':
  case '*':
  case '/':
  case '(':
   return priority(a) >= priority(b);
  case '^':
   return priority(a) > priority(b);
 }
}

variable_types: b char


decompiled_code:
__int64 __fastcall eval_operator(int a1, int a2, int a3)
{
__int64 result; // rax

if ( a3 == 45 )
return (unsigned int)(a1 - a2);
if ( a3 > 45 )
{
if ( a3 == 47 )
result = (unsigned int)(a1 / a2);
}
else if ( a3 == 42 )
{
result = (unsigned int)(a2 * a1);
}
else if ( a3 == 43 )
{
result = (unsigned int)(a1 + a2);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func17(int a1, int a2, int a3)
{
__int64 result; // rax

if ( a3 == 45 )
return (unsigned int)(a1 - a2);
if ( a3 > 45 )
{
if ( a3 == 47 )
result = (unsigned int)(a1 / a2);
}
else if ( a3 == 42 )
{
result = (unsigned int)(a2 * a1);
}
else if ( a3 == 43 )
{
result = (unsigned int)(a1 + a2);
}
return result;
}

original_code:
int eval_operator(int a, int b, int op)
{
 switch(op){
  case '*':
   return a * b;
  case '/':
   return a / b;
  case '+':
   return a + b;
  case '-':
   return a - b;
 }
}

variable_types: a int

variable_types: b int

variable_types: op int


decompiled_code:
__int64 __fastcall eval_posfix(const char *a1)
{
int v1; // er13
_DWORD *v2; // rbp
const char *v3; // rbx
__int64 v4; // r12
int v5; // er13
int v6; // eax
int v7; // eax
unsigned int v8; // ebx

v1 = strlen(a1);
v2 = mystack_new(10);
if ( v1 > 0 )
{
v3 = a1;
v4 = (__int64)&a1[v1 - 1 + 1];
do
{
if ( (unsigned __int8)(*v3 - 48) > 9u )
{
v5 = mystack_pop((__int64)v2);
v6 = mystack_pop((__int64)v2);
v7 = eval_operator(v6, v5, *v3);
mystack_push((__int64)v2, v7);
}
else
{
mystack_push((__int64)v2, *v3 - 48);
}
++v3;
}
while ( v3 != (const char *)v4 );
}
v8 = mystack_pop((__int64)v2);
mystack_free(v2);
return v8;
}

original_code:
int eval_posfix(char *expr)
{
 int ans = 0;
 int len = strlen(expr);
 mystack *s = mystack_new(10);
 int i = 0;
 for(i = 0; i < len; i++){
  if('0' <= expr[i] && expr[i] <= '9')
   mystack_push(s, expr[i] - '0');
  else{
   int b = mystack_pop(s);
   int a = mystack_pop(s);
   mystack_push(s, eval_operator(a, b, expr[i]));
  }
 }
 ans = mystack_pop(s);
 mystack_free(s);
 return ans;
}

canonical_original_code:
int eval_posfix(char *expr)
{
 int ans = 0;
 int len = strlen(expr);
 struct mystack *s = mystack_new(10);
 int i = 0;
 for(i = 0; i < len; i++){
  if('0' <= expr[i] && expr[i] <= '9')
   mystack_push(s, expr[i] - '0');
  else{
   int b = mystack_pop(s);
   int a = mystack_pop(s);
   mystack_push(s, eval_operator(a, b, expr[i]));
  }
 }
 ans = mystack_pop(s);
 mystack_free(s);
 return ans;
}

variable_types:
expr
char *

variable_types: ans int

variable_types: len int

variable_types: i int


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *v3; // rbx
unsigned int v4; // eax
char v6[120]; // [rsp+0h] [rbp-78h] BYREF

__isoc99_scanf();
v3 = infix_to_posfix(v6);
puts(v3);
v4 = eval_posfix(v3);
printf("ans:%d\n", v4);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *v3; // rbx
unsigned int v4; // eax
char v6[120]; // [rsp+0h] [rbp-78h] BYREF

__isoc99_scanf();
v3 = func16(v6);
puts(v3);
v4 = func18(v3);
printf("ans:%d\n", v4);
return 0;
}

original_code:
int main(){
 char expr[100];
 scanf("%s", expr);
 char *postfix = infix_to_posfix(expr);
 printf("%s\n", postfix);
 printf("ans:%d\n", eval_posfix(postfix));
 return 0;
}

variable_types:
expr
char [100]

variable_types:
postfix
char *


variable_types: struct _mybtree { void *value; struct _mybtree *left; struct _mybtree *right; } *


decompiled_code:
__int64 __fastcall inorder_travel(char **a1)
{
__int64 result; // rax

if ( a1 )
{
inorder_travel(a1[1]);
putchar(**a1);
result = inorder_travel(a1[2]);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func15(char **a1)
{
__int64 result; // rax

if ( a1 )
{
func15(a1[1]);
putchar(**a1);
result = func15(a1[2]);
}
return result;
}

original_code:
void inorder_travel(mybtree *root)
{
 if(root != ((void *)0)){
  inorder_travel(root->left);
  printf("%c", *(char*)(root->value));
  inorder_travel(root->right);
 }
}

canonical_original_code:
void inorder_travel(struct _mybtree *root)
{
 if(root != ((void *)0)){
  inorder_travel(root->left);
  printf("%c", *(char *)(root->value));
  inorder_travel(root->right);
 }
}


decompiled_code:
__int64 __fastcall inorder_travel_stack(__int64 a1)
{
_DWORD *v2; // rbp
char **v3; // rbx

v2 = mystack_new(10);
while ( 1 )
{
while ( a1 )
{
mystack_push((__int64)v2, a1);
a1 = *(_QWORD *)(a1 + 8);
}
if ( mystack_empty(v2) )
break;
v3 = (char **)mystack_pop((__int64)v2);
putchar(**v3);
a1 = (__int64)v3[2];
}
return mystack_free(v2);
}

canonical_decompiled_code:
__int64 __fastcall func16(__int64 a1)
{
_DWORD *v2; // rbp
char **v3; // rbx

v2 = mystack_new(10);
while ( 1 )
{
while ( a1 )
{
func8((__int64)v2, a1);
a1 = *(_QWORD *)(a1 + 8);
}
if ( func11(v2) )
break;
v3 = (char **)func9((__int64)v2);
putchar(**v3);
a1 = (__int64)v3[2];
}
return func13(v2);
}

original_code:
void inorder_travel_stack(mybtree *root)
{
 mybtree *current = root;
 mystack *s = mystack_new(10);
 while(current != ((void *)0) || !mystack_empty(s)){
  if(current != ((void *)0)){
   mystack_push(s, current);
   current = current->left;
  }
  else{
   current = (mybtree*)mystack_pop(s);
   printf("%c", *(char*)(current->value));
   current = current->right;
  }
 }
 mystack_free(s);
}

canonical_original_code:
void inorder_travel_stack(struct _mybtree *root)
{
 struct _mybtree *current = root;
 struct mystack *s = mystack_new(10);
 while(current != ((void *)0) || !mystack_empty(s)){
  if(current != ((void *)0)){
   mystack_push(s, current);
   current = current->left;
  }
  else{
   current = (struct _mybtree *)mystack_pop(s);
   printf("%c", *(char *)(current->value));
   current = current->right;
  }
 }
 mystack_free(s);
}

variable_types: struct mystack { int length; int size; struct _list { void **value; struct _list *next; } *head; } *


repo: tjordanchat/eag

decompiled_code:
void __fastcall finish_meta_rule_nullability(__int64 a1)
{
if ( !*(_DWORD *)(a1 + 16) && !*(_DWORD *)(a1 + 28) )
*(_DWORD *)(a1 + 28) = 2;
}

original_code:
static void finish_meta_rule_nullability (meta_rule mrule)
 { if (mrule -> ext) return;
   if (mrule -> empty == 0)
      mrule -> empty = 2;
 }

canonical_original_code:
static void finish_meta_rule_nullability(struct meta_rule_rec *mrule)
 { if (mrule -> ext) return;
   if (mrule -> empty == 0)
      mrule -> empty = 2;
 }

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 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 element_rec { char *eltnm; struct element_def_rec *def; }

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_terminal_classification(__int64 a1)
{
__int64 result; // rax

result = (unsigned int)(**(_BYTE **)(a1 + 32) == 0) + 2;
*(_DWORD *)a1 = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
__int64 result; // rax

result = (unsigned int)(**(_BYTE **)(a1 + 32) == 0) + 2;
*(_DWORD *)a1 = result;
return result;
}

original_code:
static void initial_terminal_classification (member m)
 { if (strlen (m -> u.terminal) != 0)
        m -> empty = 2;
   else m -> empty = 3;
 }

canonical_original_code:
static void initial_terminal_classification(struct member_rec *m)
 { if (strlen (m -> u.terminal) != 0)
        m -> empty = 2;
   else m -> empty = 3;
 }

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; } *

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 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 variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec *def; }


decompiled_code:
__int64 __fastcall initial_semiterminal_classification(__int64 a1)
{
__int64 result; // rax

result = (unsigned int)((**(_BYTE **)(a1 + 32) & 4) == 0) + 1;
*(_DWORD *)a1 = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
__int64 result; // rax

result = (unsigned int)((**(_BYTE **)(a1 + 32) & 4) == 0) + 1;
*(_DWORD *)a1 = result;
return result;
}

original_code:
static void initial_semiterminal_classification (member m)
 { cset set = m -> u.semi.set;
   if (set -> kind & 4)
        m -> empty = 1;
   else m -> empty = 2;
 }

canonical_original_code:
static void initial_semiterminal_classification(struct member_rec *m)
 { struct cset_rec *set = m -> u.semi.set;
   if (set -> kind & 4)
        m -> empty = 1;
   else m -> empty = 2;
 }

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

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

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

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 affix_list_rec { int size; int room; struct affix_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 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_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 element_def_list_rec { int size; int room; struct element_def_rec **array; }


decompiled_code:
void __fastcall unify_empty(__int64 a1, int a2)
{
if ( !*(_DWORD *)(a1 + 20) )
{
if ( a2 )
{
*(_DWORD *)(a1 + 20) = 1;
change = 1;
}
}
}

original_code:
static void unify_empty (rule srule, int empty)
 { if (srule -> empty) return;
   if (!empty) return;
   srule -> empty = 1;
   change = 1;
 }

canonical_original_code:
static void unify_empty(struct rule_rec *srule, int empty)
 { if (srule -> empty) return;
   if (!empty) return;
   srule -> empty = 1;
   change = 1;
 }

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: empty int

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 pos_list_rec { int size; int room; struct pos_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 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 mark_if_rule_never_produces_empty(__int64 a1)
{
if ( !*(_DWORD *)(a1 + 20) )
{
*(_DWORD *)(a1 + 20) = 2;
*(_DWORD *)(a1 + 16) = 1;
}
}

original_code:
static void mark_if_rule_never_produces_empty (rule srule)
 { if (srule -> empty) return;
   srule -> empty = 2;
   srule -> kind = 1;
 }

canonical_original_code:
static void mark_if_rule_never_produces_empty(struct rule_rec *srule)
 { if (srule -> empty) return;
   srule -> empty = 2;
   srule -> kind = 1;
 }

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 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 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 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:
__int64 __fastcall member_always_produces_empty(__int64 a1)
{
__int64 result; // rax
__int64 v2; // rdx

result = *(unsigned int *)(a1 + 24);
if ( (_DWORD)result )
return *(_DWORD *)a1 == 3;
v2 = *(_QWORD *)(a1 + 48);
if ( *(_DWORD *)(v2 + 20) != 2 )
result = *(_DWORD *)(v2 + 16) != 1;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1)
{
__int64 result; // rax
__int64 v2; // rdx

result = *(unsigned int *)(a1 + 24);
if ( (_DWORD)result )
return *(_DWORD *)a1 == 3;
v2 = *(_QWORD *)(a1 + 48);
if ( *(_DWORD *)(v2 + 20) != 2 )
result = *(_DWORD *)(v2 + 16) != 1;
return result;
}

original_code:
static int member_always_produces_empty (member m)
 { if (m -> tag == 0)
      { rule def = m -> u.call.def;
        if (def -> empty == 2) return (0);
        return (def -> kind != 1);
      }
   else return (m -> empty == 3);
 }

canonical_original_code:
static int member_always_produces_empty(struct member_rec *m)
 { if (m -> tag == 0)
      { struct rule_rec *def = m -> u.call.def;
        if (def -> empty == 2) return (0);
        return (def -> kind != 1);
      }
   else return (m -> empty == 3);
 }

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 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 pos_list_rec { int size; int room; struct pos_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 affix_list_rec { int size; int room; struct affix_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 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_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 element_def_list_rec { int size; int room; struct element_def_rec **array; }


decompiled_code:
void __fastcall mark_if_rule_always_produces_empty(_DWORD *a1)
{
if ( !a1[7] && a1[4] != 1 )
{
a1[5] = 3;
a1[4] = 2;
}
}

original_code:
static void mark_if_rule_always_produces_empty (rule srule)
 { if (srule -> ext) return;
   if (srule -> kind == 1) return;
   srule -> empty = 3;
   srule -> kind = 2;
 }

canonical_original_code:
static void mark_if_rule_always_produces_empty(struct rule_rec *srule)
 { if (srule -> ext) return;
   if (srule -> kind == 1) return;
   srule -> empty = 3;
   srule -> kind = 2;
 }

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 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 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 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 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 finish_marking_in_member(__int64 a1)
{
__int64 result; // rax

if ( !*(_DWORD *)(a1 + 24) )
{
result = *(unsigned int *)(*(_QWORD *)(a1 + 48) + 20LL);
*(_DWORD *)a1 = result;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1)
{
__int64 result; // rax

if ( !*(_DWORD *)(a1 + 24) )
{
result = *(unsigned int *)(*(_QWORD *)(a1 + 48) + 20LL);
*(_DWORD *)a1 = result;
}
return result;
}

original_code:
static void finish_marking_in_member (member m)
 { if (m -> tag != 0) return;
   m -> empty = m -> u.call.def -> empty;
 }

canonical_original_code:
static void finish_marking_in_member(struct member_rec *m)
 { if (m -> tag != 0) return;
   m -> empty = m -> u.call.def -> empty;
 }

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 semiterminal_rec { struct cset_rec *set; struct pos_list_rec *display; }

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 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_list_rec { int size; int room; struct affix_rec **array; }

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; }

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 value_list_rec { int size; int room; struct value_rec **array; }


original_code:
static void finish_marking_in_alt (alt a)
 { member_list mems = a -> members;
   int ix;
   if (mems == ((member_list) ((void *)0))) return;
   for (ix = 0; ix < mems -> size; ix++)
      finish_marking_in_member (mems -> array[ix]);
   for (ix = 0; ix < mems -> size; ix++)
      if (mems -> array[ix] -> empty == 2) return;
   a -> empty = 1;
 }

canonical_original_code:
static void finish_marking_in_alt(struct alt_rec *a)
 { struct member_list_rec *mems = a -> members;
   int ix;
   if (mems == ((member_list) ((void *)0))) return;
   for (ix = 0; ix < mems -> size; ix++)
      finish_marking_in_member (mems -> array[ix]);
   for (ix = 0; ix < mems -> size; ix++)
      if (mems -> array[ix] -> empty == 2) return;
   a -> empty = 1;
 }

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: 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 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 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 meta_alt_list_rec { int size; int room; struct meta_alt_rec **array; }


decompiled_code:
void finish_rule_marking()
{
__int64 v0; // rbx

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

canonical_decompiled_code:
void func13()
{
__int64 v0; // rbx

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

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

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


decompiled_code:
void determine_user_predicates()
{
__int64 v0; // rbx
unsigned int v1; // ebp
__int64 v2; // rbx
const char *v3; // rdx
__int64 v4; // rbx

if ( nr_of_rules > 0 )
{
v0 = 0LL;
do
mark_if_rule_never_produces_empty(*(_QWORD *)(all_rules + 8 * v0++));
while ( nr_of_rules > (int)v0 );
}
hint("detecting user defined predicates...");
v1 = 0;
while ( 1 )
{
change = 0;
if ( nr_of_rules <= 0 )
break;
v2 = 0LL;
do
detect_if_rule_always_produces_empty(*(_QWORD *)(all_rules + 8 * v2++));
while ( nr_of_rules > (int)v2 );
++v1;
if ( !change )
goto LABEL_11;
}
++v1;
LABEL_11:
v3 = (const char *)&unk_9A0;
if ( v1 != 1 )
v3 = (const char *)&unk_9A1;
hint("needed %d pass%s for predicate detection", v1, v3);
if ( nr_of_rules > 0 )
{
v4 = 0LL;
do
mark_if_rule_always_produces_empty(*(_DWORD **)(all_rules + 8 * v4++));
while ( nr_of_rules > (int)v4 );
}
}

canonical_decompiled_code:
void func14()
{
__int64 v0; // rbx
unsigned int v1; // ebp
__int64 v2; // rbx
const char *v3; // rdx
__int64 v4; // rbx

if ( nr_of_rules > 0 )
{
v0 = 0LL;
do
func5(*(_QWORD *)(all_rules + 8 * v0++));
while ( nr_of_rules > (int)v0 );
}
hint("detecting user defined predicates...");
v1 = 0;
while ( 1 )
{
change = 0;
if ( nr_of_rules <= 0 )
break;
v2 = 0LL;
do
func8(*(_QWORD *)(all_rules + 8 * v2++));
while ( nr_of_rules > (int)v2 );
++v1;
if ( !change )
goto LABEL_11;
}
++v1;
LABEL_11:
v3 = (const char *)&unk_9A0;
if ( v1 != 1 )
v3 = (const char *)&unk_9A1;
hint("needed %d pass%s for predicate detection", v1, v3);
if ( nr_of_rules > 0 )
{
v4 = 0LL;
do
func9(*(_DWORD **)(all_rules + 8 * v4++));
while ( nr_of_rules > (int)v4 );
}
}

original_code:
static void determine_user_predicates ()
 { int nr_passes;
   int ix;
   for (ix = 0; ix < nr_of_rules; ix++)
      mark_if_rule_never_produces_empty (all_rules [ix]);
   hint ("detecting user defined predicates...");
   nr_passes = 0;
   do { change = 0;
        for (ix = 0; ix < nr_of_rules; ix++)
    detect_if_rule_always_produces_empty (all_rules [ix]);
        nr_passes++;
      }
   while (change);
   hint ("needed %d pass%s for predicate detection",
  nr_passes, (nr_passes == 1)?"":"es");
   for (ix = 0; ix < nr_of_rules; ix++)
      mark_if_rule_always_produces_empty (all_rules [ix]);
 }

canonical_original_code:
static void determine_user_predicates()
 { int nr_passes;
   int ix;
   for (ix = 0; ix < nr_of_rules; ix++)
      mark_if_rule_never_produces_empty (all_rules [ix]);
   hint ("detecting user defined predicates...");
   nr_passes = 0;
   do { change = 0;
        for (ix = 0; ix < nr_of_rules; ix++)
    detect_if_rule_always_produces_empty (all_rules [ix]);
        nr_passes++;
      }
   while (change);
   hint ("needed %d pass%s for predicate detection",
  nr_passes, (nr_passes == 1)?"":"es");
   for (ix = 0; ix < nr_of_rules; ix++)
      mark_if_rule_always_produces_empty (all_rules [ix]);
 }


decompiled_code:
__int64 __fastcall affix_nullability(__int64 a1)
{
__int64 result; // rax

result = *(unsigned int *)(a1 + 40);
switch ( (int)result )
{
case 0:
result = *(unsigned int *)(*(_QWORD *)(a1 + 64) + 28LL);
break;
case 1:
if ( **(_BYTE **)(a1 + 48) )
result = 2LL;
break;
case 2:
if ( *(int *)(a1 + 48) <= 0 )
result = 1LL;
break;
case 3:
if ( *(double *)(a1 + 48) == 0.0 )
result = 1LL;
else
result = 2LL;
break;
case 4:
result = (unsigned int)((**(_BYTE **)(a1 + 48) & 4) == 0) + 1;
break;
case 5:
result = 2LL;
break;
default:
bad_tag((unsigned int)result, "affix_may_produce_empty");
result = 0LL;
break;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func15(__int64 a1)
{
__int64 result; // rax

result = *(unsigned int *)(a1 + 40);
switch ( (int)result )
{
case 0:
result = *(unsigned int *)(*(_QWORD *)(a1 + 64) + 28LL);
break;
case 1:
if ( **(_BYTE **)(a1 + 48) )
result = 2LL;
break;
case 2:
if ( *(int *)(a1 + 48) <= 0 )
result = 1LL;
break;
case 3:
if ( *(double *)(a1 + 48) == 0.0 )
result = 1LL;
else
result = 2LL;
break;
case 4:
result = (unsigned int)((**(_BYTE **)(a1 + 48) & 4) == 0) + 1;
break;
case 5:
result = 2LL;
break;
default:
bad_tag((unsigned int)result, "affix_may_produce_empty");
result = 0LL;
break;
}
return result;
}

original_code:
static int affix_nullability (affix a)
 { switch (a -> tag)
      { case 0:
    { meta_rule def = a -> u.var.def;
      return (def -> empty);
    };
        case 1:
    if (strlen (a -> u.str)) return (2);
    else return (1);
        case 2:
    if (a -> u.inum <= 0) return (1);
    else return (2);
        case 3:
    if (a -> u.rnum == 0.0) return (1);
    else return (2);
        case 4:
    { cset set = a -> u.semi;
      if (set -> kind & 4) return (1);
      else return (2);
    };
        case 5: return (2);
        default: bad_tag (a -> tag, "affix_may_produce_empty");
      };
   return (0);
 }

canonical_original_code:
static int affix_nullability(struct affix_rec *a)
 { switch (a -> tag)
      { case 0:
    { struct meta_rule_rec *def = a -> u.var.def;
      return (def -> empty);
    };
        case 1:
    if (strlen (a -> u.str)) return (2);
    else return (1);
        case 2:
    if (a -> u.inum <= 0) return (1);
    else return (2);
        case 3:
    if (a -> u.rnum == 0.0) return (1);
    else return (2);
        case 4:
    { struct cset_rec *set = a -> u.semi;
      if (set -> kind & 4) return (1);
      else return (2);
    };
        case 5: return (2);
        default: bad_tag (a -> tag, "affix_may_produce_empty");
      };
   return (0);
 }

variable_types: 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 { int tag; union { struct affix_rec *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 { 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; } *

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 meta_alt_rec { struct expr_rec *e; int number; }

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 concat_nullability(__int64 a1)
{
__int64 result; // rax
int v2; // er12
__int64 v3; // rbx
int v4; // ebp

result = affix_nullability(**(_QWORD **)(a1 + 8));
v2 = result;
if ( (_DWORD)result != 2 )
{
v3 = 8LL;
v4 = 1;
do
{
result = affix_nullability(*(_QWORD *)(*(_QWORD *)(a1 + 8) + v3));
if ( (_DWORD)result == 2 )
break;
if ( v2 != (_DWORD)result )
result = 0LL;
v2 = result;
++v4;
v3 += 8LL;
}
while ( *(_DWORD *)a1 > v4 );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func16(__int64 a1)
{
__int64 result; // rax
int v2; // er12
__int64 v3; // rbx
int v4; // ebp

result = func15(**(_QWORD **)(a1 + 8));
v2 = result;
if ( (_DWORD)result != 2 )
{
v3 = 8LL;
v4 = 1;
do
{
result = func15(*(_QWORD *)(*(_QWORD *)(a1 + 8) + v3));
if ( (_DWORD)result == 2 )
break;
if ( v2 != (_DWORD)result )
result = 0LL;
v2 = result;
++v4;
v3 += 8LL;
}
while ( *(_DWORD *)a1 > v4 );
}
return result;
}

original_code:
static int concat_nullability (affix_list affs)
 { int null = affix_nullability (affs -> array[0]);
   int ix = 1;
   if (null == 2) return (2);
   do
      { int null2 = affix_nullability (affs -> array[ix]);
        if (null2 == 2) return (2);
        if (null != null2) null = 0;
        ix++;
      }
   while (ix < affs -> size);
   return (null);
 }

canonical_original_code:
static int concat_nullability(struct affix_list_rec *affs)
 { int null = affix_nullability (affs -> array[0]);
   int ix = 1;
   if (null == 2) return (2);
   do
      { int null2 = affix_nullability (affs -> array[ix]);
        if (null2 == 2) return (2);
        if (null != null2) null = 0;
        ix++;
      }
   while (ix < affs -> size);
   return (null);
 }

variable_types: struct affix_list_rec { int size; int room; 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 { int tag; union { struct affix_rec *single; struct affix_list_rec *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 { 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; } **array; } *

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


decompiled_code:
__int64 __fastcall expr_nullability(unsigned int *a1)
{
__int64 result; // rax

if ( !a1 )
return 1LL;
result = *a1;
if ( (_DWORD)result == 3 )
return concat_nullability(*((_QWORD *)a1 + 1));
if ( (int)result > 3 )
{
if ( (_DWORD)result == 4 )
return 2LL;
LABEL_8:
bad_tag((unsigned int)result, "expr_nullability");
return 0LL;
}
if ( (_DWORD)result == 1 )
return affix_nullability(*((_QWORD *)a1 + 1));
if ( (_DWORD)result != 2 )
goto LABEL_8;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func17(unsigned int *a1)
{
__int64 result; // rax

if ( !a1 )
return 1LL;
result = *a1;
if ( (_DWORD)result == 3 )
return func16(*((_QWORD *)a1 + 1));
if ( (int)result > 3 )
{
if ( (_DWORD)result == 4 )
return 2LL;
LABEL_8:
bad_tag((unsigned int)result, "expr_nullability");
return 0LL;
}
if ( (_DWORD)result == 1 )
return func15(*((_QWORD *)a1 + 1));
if ( (_DWORD)result != 2 )
goto LABEL_8;
return result;
}

original_code:
static int expr_nullability (expr e)
 { if (e == ((expr) ((void *)0)))
      return (1);
   switch (e -> tag)
      { case 1: return (affix_nullability (e -> u.single));
        case 3: return (concat_nullability (e -> u.concat));
        case 2: return (2);
        case 4: return (2);
        default: bad_tag (e -> tag, "expr_nullability");
      };
   return (0);
 }

canonical_original_code:
static int expr_nullability(struct expr_rec *e)
 { if (e == ((expr) ((void *)0)))
      return (1);
   switch (e -> tag)
      { case 1: return (affix_nullability (e -> u.single));
        case 3: return (concat_nullability (e -> u.concat));
        case 2: return (2);
        case 4: return (2);
        default: bad_tag (e -> tag, "expr_nullability");
      };
   return (0);
 }

variable_types: 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; } *

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 variable_rec { char *nonterminal; char *suffix; struct meta_rule_rec *def; }


decompiled_code:
__int64 __fastcall meta_alts_nullability(__int64 a1)
{
__int64 result; // rax
int v2; // er12
__int64 v3; // rbx
int v4; // ebp

result = expr_nullability(***(unsigned int ****)(a1 + 8));
if ( (_DWORD)result != 1 )
{
v2 = result;
if ( *(int *)a1 > 1 )
{
v3 = 8LL;
v4 = 1;
do
{
result = expr_nullability(**(unsigned int ***)(*(_QWORD *)(a1 + 8) + v3));
if ( (_DWORD)result == 1 )
break;
if ( (_DWORD)result != v2 )
result = 0LL;
v2 = result;
++v4;
v3 += 8LL;
}
while ( *(_DWORD *)a1 > v4 );
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func18(__int64 a1)
{
__int64 result; // rax
int v2; // er12
__int64 v3; // rbx
int v4; // ebp

result = func17(***(unsigned int ****)(a1 + 8));
if ( (_DWORD)result != 1 )
{
v2 = result;
if ( *(int *)a1 > 1 )
{
v3 = 8LL;
v4 = 1;
do
{
result = func17(**(unsigned int ***)(*(_QWORD *)(a1 + 8) + v3));
if ( (_DWORD)result == 1 )
break;
if ( (_DWORD)result != v2 )
result = 0LL;
v2 = result;
++v4;
v3 += 8LL;
}
while ( *(_DWORD *)a1 > v4 );
}
}
return result;
}

original_code:
static int meta_alts_nullability (meta_alt_list alts)
 { int null = expr_nullability (alts -> array[0] -> e);
   int ix = 1;
   if (null == 1) return (1);
   for (ix = 1; ix < alts -> size; ix++)
      { int null2 = expr_nullability (alts -> array[ix] -> e);
        if (null2 == 1) return (1);
        if (null != null2) null = 0;
      };
   return (null);
 }

canonical_original_code:
static int meta_alts_nullability(struct meta_alt_list_rec *alts)
 { int null = expr_nullability (alts -> array[0] -> e);
   int ix = 1;
   if (null == 1) return (1);
   for (ix = 1; ix < alts -> size; ix++)
      { int null2 = expr_nullability (alts -> array[ix] -> e);
        if (null2 == 1) return (1);
        if (null != null2) null = 0;
      };
   return (null);
 }

variable_types: 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 { 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 { 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; } *e; int number; } **array; } *


decompiled_code:
void __fastcall detect_meta_rule_nullability(__int64 a1)
{
int v1; // eax
int v2; // edx

if ( !*(_DWORD *)(a1 + 16) )
{
v1 = meta_alts_nullability(*(_QWORD *)(a1 + 8));
v2 = *(_DWORD *)(a1 + 28);
if ( v2 != v1 )
{
if ( v2 )
{
internal_error("detect_meta_rule_nullability");
}
else
{
*(_DWORD *)(a1 + 28) = v1;
change = 1;
}
}
}
}

canonical_decompiled_code:
void __fastcall func19(__int64 a1)
{
int v1; // eax
int v2; // edx

if ( !*(_DWORD *)(a1 + 16) )
{
v1 = func18(*(_QWORD *)(a1 + 8));
v2 = *(_DWORD *)(a1 + 28);
if ( v2 != v1 )
{
if ( v2 )
{
internal_error("detect_meta_rule_nullability");
}
else
{
*(_DWORD *)(a1 + 28) = v1;
change = 1;
}
}
}
}

original_code:
static void detect_meta_rule_nullability (meta_rule mrule)
 { int null;
   if (mrule -> ext) return;
   null = meta_alts_nullability (mrule -> alts);
   if (mrule -> empty == null) return;
   if (mrule -> empty == 0)
      { mrule -> empty = null;
        change = 1;
        return;
      };
   internal_error ("detect_meta_rule_nullability");
 }

canonical_original_code:
static void detect_meta_rule_nullability(struct meta_rule_rec *mrule)
 { int null;
   if (mrule -> ext) return;
   null = meta_alts_nullability (mrule -> alts);
   if (mrule -> empty == null) return;
   if (mrule -> empty == 0)
      { mrule -> empty = null;
        change = 1;
        return;
      };
   internal_error ("detect_meta_rule_nullability");
 }

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 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 detect_empty_producing_meta_rules()
{
unsigned int v0; // ebp
__int64 v1; // rbx
const char *v2; // rdx
__int64 v3; // rbx

hint("detecting empty producing meta rules...");
v0 = 0;
while ( 1 )
{
change = 0;
if ( nr_of_meta_rules <= 0 )
break;
v1 = 0LL;
do
detect_meta_rule_nullability(*(_QWORD *)(all_meta_rules + 8 * v1++));
while ( nr_of_meta_rules > (int)v1 );
++v0;
if ( !change )
goto LABEL_8;
}
++v0;
LABEL_8:
v2 = (const char *)&unk_9A0;
if ( v0 != 1 )
v2 = (const char *)&unk_9A1;
hint("needed %d pass%s for empty detection of meta rules", v0, v2);
if ( nr_of_meta_rules > 0 )
{
v3 = 0LL;
do
finish_meta_rule_nullability(*(_QWORD *)(all_meta_rules + 8 * v3++));
while ( nr_of_meta_rules > (int)v3 );
}
}

canonical_decompiled_code:
void func20()
{
unsigned int v0; // ebp
__int64 v1; // rbx
const char *v2; // rdx
__int64 v3; // rbx

hint("detecting empty producing meta rules...");
v0 = 0;
while ( 1 )
{
change = 0;
if ( nr_of_meta_rules <= 0 )
break;
v1 = 0LL;
do
func19(*(_QWORD *)(all_meta_rules + 8 * v1++));
while ( nr_of_meta_rules > (int)v1 );
++v0;
if ( !change )
goto LABEL_8;
}
++v0;
LABEL_8:
v2 = (const char *)&unk_9A0;
if ( v0 != 1 )
v2 = (const char *)&unk_9A1;
hint("needed %d pass%s for empty detection of meta rules", v0, v2);
if ( nr_of_meta_rules > 0 )
{
v3 = 0LL;
do
func0(*(_QWORD *)(all_meta_rules + 8 * v3++));
while ( nr_of_meta_rules > (int)v3 );
}
}

original_code:
static void detect_empty_producing_meta_rules ()
 { int nr_passes;
   int ix;
   hint ("detecting empty producing meta rules...");
   nr_passes = 0;
   do
      { change = 0;
        for (ix = 0; ix < nr_of_meta_rules; ix++)
    detect_meta_rule_nullability (all_meta_rules[ix]);
        nr_passes++;
      }
   while (change);
   hint ("needed %d pass%s for empty detection of meta rules",
  nr_passes, (nr_passes == 1)?"":"es");
   for (ix = 0; ix < nr_of_meta_rules; ix++)
      finish_meta_rule_nullability (all_meta_rules[ix]);
 }

canonical_original_code:
static void detect_empty_producing_meta_rules()
 { int nr_passes;
   int ix;
   hint ("detecting empty producing meta rules...");
   nr_passes = 0;
   do
      { change = 0;
        for (ix = 0; ix < nr_of_meta_rules; ix++)
    detect_meta_rule_nullability (all_meta_rules[ix]);
        nr_passes++;
      }
   while (change);
   hint ("needed %d pass%s for empty detection of meta rules",
  nr_passes, (nr_passes == 1)?"":"es");
   for (ix = 0; ix < nr_of_meta_rules; ix++)
      finish_meta_rule_nullability (all_meta_rules[ix]);
 }


decompiled_code:
void __fastcall initial_member_classification(__int64 a1, _DWORD *a2)
{
__int64 v3; // rdi

v3 = (unsigned int)a2[6];
if ( (_DWORD)v3 == 2 )
{
initial_semiterminal_classification((__int64)a2);
}
else
{
if ( (int)v3 > 2 )
{
if ( (_DWORD)v3 == 3 )
{
initial_cut_classification(a2);
goto LABEL_6;
}
}
else
{
if ( !(_DWORD)v3 )
return;
if ( (_DWORD)v3 == 1 )
{
initial_terminal_classification((__int64)a2);
goto LABEL_6;
}
}
bad_tag(v3, "initial_member_classification");
}
LABEL_6:
if ( *a2 != 3 )
*(_DWORD *)(a1 + 16) = 1;
}

canonical_decompiled_code:
void __fastcall func21(__int64 a1, _DWORD *a2)
{
__int64 v3; // rdi

v3 = (unsigned int)a2[6];
if ( (_DWORD)v3 == 2 )
{
func2((__int64)a2);
}
else
{
if ( (int)v3 > 2 )
{
if ( (_DWORD)v3 == 3 )
{
func3(a2);
goto LABEL_6;
}
}
else
{
if ( !(_DWORD)v3 )
return;
if ( (_DWORD)v3 == 1 )
{
func1((__int64)a2);
goto LABEL_6;
}
}
bad_tag(v3, "initial_member_classification");
}
LABEL_6:
if ( *a2 != 3 )
*(_DWORD *)(a1 + 16) = 1;
}

original_code:
static void initial_member_classification (rule srule, member m)
 { switch (m -> tag)
      { case 0: return;
        case 1:
    initial_terminal_classification (m); break;
        case 2:
    initial_semiterminal_classification (m); break;
        case 3:
    initial_cut_classification (m); break;
        default: bad_tag (m -> tag, "initial_member_classification");
      };
   if (m -> empty != 3)
      srule -> kind = 1;
 }

canonical_original_code:
static void initial_member_classification(struct rule_rec *srule, struct member_rec *m)
 { switch (m -> tag)
      { case 0: return;
        case 1:
    initial_terminal_classification (m); break;
        case 2:
    initial_semiterminal_classification (m); break;
        case 3:
    initial_cut_classification (m); break;
        default: bad_tag (m -> tag, "initial_member_classification");
      };
   if (m -> empty != 3)
      srule -> kind = 1;
 }

variable_types:
m
struct member_rec *

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_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 pos_list_rec { int size; int room; struct pos_rec **array; }

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 pos_rec { int kind; struct expr_rec *ex; int type; struct element_def_rec *lat_repr; }

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 semiterminal_rec { struct cset_rec *set; struct pos_list_rec *display; }

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 value_list_rec { int size; int room; struct value_rec **array; }


decompiled_code:
void __fastcall initial_rule_classification(__int64 a1)
{
__int64 v1; // rbp
__int64 i; // rbx

if ( *(_DWORD *)(a1 + 28) )
{
*(_DWORD *)(a1 + 20) = 3;
}
else
{
v1 = *(_QWORD *)(a1 + 8);
for ( i = 0LL; *(_DWORD *)v1 > (int)i; ++i )
initial_alt_classification(a1, *(_QWORD *)(*(_QWORD *)(v1 + 8) + 8 * i));
}
}

original_code:
static void initial_rule_classification (rule srule)
 { alt_list alts = srule -> alts;
   int ix;
   if (srule -> ext) srule -> empty = 3;
   else
      for (ix = 0; ix < alts -> size; ix++)
         initial_alt_classification (srule, alts -> array[ix]);
 }

canonical_original_code:
static void initial_rule_classification(struct rule_rec *srule)
 { struct alt_list_rec *alts = srule -> alts;
   int ix;
   if (srule -> ext) srule -> empty = 3;
   else
      for (ix = 0; ix < alts -> size; ix++)
         initial_alt_classification (srule, alts -> array[ix]);
 }

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 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 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 call_rec { char *nonterminal; struct pos_list_rec *display; struct rule_rec *def; }

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_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 do_initial_rule_classification()
{
__int64 v0; // rbx

hint("initial rule classification...");
if ( nr_of_rules > 0 )
{
v0 = 0LL;
do
initial_rule_classification(*(_QWORD *)(all_rules + 8 * v0++));
while ( nr_of_rules > (int)v0 );
}
}

canonical_decompiled_code:
void func24()
{
__int64 v0; // rbx

hint("initial rule classification...");
if ( nr_of_rules > 0 )
{
v0 = 0LL;
do
func23(*(_QWORD *)(all_rules + 8 * v0++));
while ( nr_of_rules > (int)v0 );
}
}

original_code:
static void do_initial_rule_classification ()
 { int ix;
   hint ("initial rule classification...");
   for (ix = 0; ix < nr_of_rules; ix++)
      initial_rule_classification (all_rules [ix]);
 }

canonical_original_code:
static void do_initial_rule_classification()
 { int ix;
   hint ("initial rule classification...");
   for (ix = 0; ix < nr_of_rules; ix++)
      initial_rule_classification (all_rules [ix]);
 }


decompiled_code:
_BOOL8 __fastcall member_may_produce_empty(__int64 a1)
{
unsigned int v1; // eax

v1 = *(_DWORD *)(a1 + 24);
if ( !v1 )
return (*(_DWORD *)(*(_QWORD *)(a1 + 48) + 20LL) & 0xFFFFFFFD) == 1;
if ( v1 - 1 <= 2 )
return *(_DWORD *)a1 != 2;
bad_tag(v1, "member_may_produce_empty");
return 0LL;
}

canonical_decompiled_code:
_BOOL8 __fastcall func25(__int64 a1)
{
unsigned int v1; // eax

v1 = *(_DWORD *)(a1 + 24);
if ( !v1 )
return (*(_DWORD *)(*(_QWORD *)(a1 + 48) + 20LL) & 0xFFFFFFFD) == 1;
if ( v1 - 1 <= 2 )
return *(_DWORD *)a1 != 2;
bad_tag(v1, "member_may_produce_empty");
return 0LL;
}

original_code:
static int member_may_produce_empty (member m)
 { switch (m -> tag)
      { case 0:
           { int empty = m -> u.call.def -> empty;
             if (empty == 1) return (1);
             return (empty == 3);
    };
        case 1:
        case 2:
        case 3:
      return (m -> empty != 2);
        default: bad_tag (m -> tag, "member_may_produce_empty");
      };
   return (0);
 }

canonical_original_code:
static int member_may_produce_empty(struct member_rec *m)
 { switch (m -> tag)
      { case 0:
           { int empty = m -> u.call.def -> empty;
             if (empty == 1) return (1);
             return (empty == 3);
    };
        case 1:
        case 2:
        case 3:
      return (m -> empty != 2);
        default: bad_tag (m -> tag, "member_may_produce_empty");
      };
   return (0);
 }

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_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 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 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 detect_if_rule_produces_empty(__int64 a1)
{
__int64 v1; // rbp
__int64 v2; // rbx
int v3; // eax

if ( !*(_DWORD *)(a1 + 28) )
{
v1 = *(_QWORD *)(a1 + 8);
if ( *(int *)v1 > 0 )
{
v2 = 0LL;
do
{
v3 = alt_may_produce_empty(*(_QWORD *)(*(_QWORD *)(v1 + 8) + 8 * v2));
unify_empty(a1, v3);
++v2;
}
while ( *(_DWORD *)v1 > (int)v2 );
}
}
}

original_code:
static void detect_if_rule_produces_empty (rule srule)
 { int ix;
   alt_list alts = srule -> alts;
   if (srule -> ext) return;
   for (ix = 0; ix < alts -> size; ix++)
      unify_empty (srule, alt_may_produce_empty (alts -> array[ix]));
 }

canonical_original_code:
static void detect_if_rule_produces_empty(struct rule_rec *srule)
 { int ix;
   struct alt_list_rec *alts = srule -> alts;
   if (srule -> ext) return;
   for (ix = 0; ix < alts -> size; ix++)
      unify_empty (srule, alt_may_produce_empty (alts -> array[ix]));
 }

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 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 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 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_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 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 value_list_rec { int size; int room; struct value_rec **array; }


decompiled_code:
__int64 detect_empty_producing_rules()
{
unsigned int v0; // ebp
__int64 v1; // rbx
const char *v2; // rdx

hint("detecting empty producing rules...");
v0 = 0;
while ( 1 )
{
change = 0;
if ( nr_of_rules <= 0 )
break;
v1 = 0LL;
do
detect_if_rule_produces_empty(*(_QWORD *)(all_rules + 8 * v1++));
while ( nr_of_rules > (int)v1 );
++v0;
if ( !change )
goto LABEL_8;
}
++v0;
LABEL_8:
v2 = (const char *)&unk_9A0;
if ( v0 != 1 )
v2 = (const char *)&unk_9A1;
return hint("needed %d pass%s for empty detection", v0, v2);
}

canonical_decompiled_code:
__int64 func28()
{
unsigned int v0; // ebp
__int64 v1; // rbx
const char *v2; // rdx

hint("detecting empty producing rules...");
v0 = 0;
while ( 1 )
{
change = 0;
if ( nr_of_rules <= 0 )
break;
v1 = 0LL;
do
func27(*(_QWORD *)(all_rules + 8 * v1++));
while ( nr_of_rules > (int)v1 );
++v0;
if ( !change )
goto LABEL_8;
}
++v0;
LABEL_8:
v2 = (const char *)&unk_9A0;
if ( v0 != 1 )
v2 = (const char *)&unk_9A1;
return hint("needed %d pass%s for empty detection", v0, v2);
}

original_code:
static void detect_empty_producing_rules ()
 { int nr_passes;
   int ix;
   hint ("detecting empty producing rules...");
   nr_passes = 0;
   do
      { change = 0;
        for (ix = 0; ix < nr_of_rules; ix++)
    detect_if_rule_produces_empty (all_rules [ix]);
        nr_passes++;
      }
   while (change);
   hint ("needed %d pass%s for empty detection",
  nr_passes, (nr_passes == 1)?"":"es");
 }

canonical_original_code:
static void detect_empty_producing_rules()
 { int nr_passes;
   int ix;
   hint ("detecting empty producing rules...");
   nr_passes = 0;
   do
      { change = 0;
        for (ix = 0; ix < nr_of_rules; ix++)
    detect_if_rule_produces_empty (all_rules [ix]);
        nr_passes++;
      }
   while (change);
   hint ("needed %d pass%s for empty detection",
  nr_passes, (nr_passes == 1)?"":"es");
 }


decompiled_code:
__int64 check_layout_rule()
{
__int64 result; // rax

if ( layoutflag )
{
result = layout_rule;
if ( (*(_BYTE *)(layout_rule + 16LL) & 1) == 0 )
result = panic("rule layout should be a non predicate");
}
return result;
}

canonical_decompiled_code:
__int64 func29()
{
__int64 result; // rax

if ( layoutflag )
{
result = layout_rule;
if ( (*(_BYTE *)(layout_rule + 16LL) & 1) == 0 )
result = panic("rule layout should be a non predicate");
}
return result;
}

original_code:
static void check_layout_rule ()
 { if (!layoutflag) return;
   if (layout_rule -> kind & 1) return;
   panic ("rule layout should be a non predicate");
 }

canonical_original_code:
static void check_layout_rule()
 { if (!layoutflag) return;
   if (layout_rule -> kind & 1) return;
   panic ("rule layout should be a non predicate");
 }


decompiled_code:
__int64 __fastcall report_empty_detection_for_rule(__int64 a1)
{
int v1; // eax
int v2; // eax

v1 = *(_DWORD *)(a1 + 16);
if ( (v1 & 2) != 0 )
{
eprint_log("predicate");
}
else if ( (v1 & 4) != 0 )
{
eprint_log("semipredicate");
}
else if ( (v1 & 1) != 0 )
{
eprint_log("rule");
}
else
{
eprint_log("?? rule ??");
}
eprint_log(" %s ", *(const char **)a1);
v2 = *(_DWORD *)(a1 + 20);
switch ( v2 )
{
case 2:
eprint_log("never produces empty");
break;
case 3:
eprint_log("always produces empty");
break;
case 1:
eprint_log("may produce empty");
break;
default:
eprint_log("may or may not produce empty");
break;
}
return eprint_log("\n");
}

canonical_decompiled_code:
__int64 __fastcall func30(__int64 a1)
{
int v1; // eax
int v2; // eax

v1 = *(_DWORD *)(a1 + 16);
if ( (v1 & 2) != 0 )
{
eprint_log("predicate");
}
else if ( (v1 & 4) != 0 )
{
eprint_log("semipredicate");
}
else if ( (v1 & 1) != 0 )
{
eprint_log("rule");
}
else
{
eprint_log("?? rule ??");
}
eprint_log(" %s ", *(const char **)a1);
v2 = *(_DWORD *)(a1 + 20);
switch ( v2 )
{
case 2:
eprint_log("never produces empty");
break;
case 3:
eprint_log("always produces empty");
break;
case 1:
eprint_log("may produce empty");
break;
default:
eprint_log("may or may not produce empty");
break;
}
return eprint_log("\n");
}

original_code:
static void report_empty_detection_for_rule (rule srule)
 { if (srule -> kind & 2) eprint_log ("predicate");
   else if (srule -> kind & 4)
       eprint_log ("semipredicate");
   else if (srule -> kind & 1) eprint_log ("rule");
   else eprint_log ("?? rule ??");
   eprint_log (" %s ", srule -> nonterminal);
   switch (srule -> empty)
      { case 1:
    eprint_log ("may produce empty");
    break;
        case 2:
    eprint_log ("never produces empty");
    break;
        case 3:
    eprint_log ("always produces empty");
    break;
        default: eprint_log ("may or may not produce empty");
      };
   eprint_log ("\n");
 }

canonical_original_code:
static void report_empty_detection_for_rule(struct rule_rec *srule)
 { if (srule -> kind & 2) eprint_log ("predicate");
   else if (srule -> kind & 4)
       eprint_log ("semipredicate");
   else if (srule -> kind & 1) eprint_log ("rule");
   else eprint_log ("?? rule ??");
   eprint_log (" %s ", srule -> nonterminal);
   switch (srule -> empty)
      { case 1:
    eprint_log ("may produce empty");
    break;
        case 2:
    eprint_log ("never produces empty");
    break;
        case 3:
    eprint_log ("always produces empty");
    break;
        default: eprint_log ("may or may not produce empty");
      };
   eprint_log ("\n");
 }

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_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 pos_list_rec { int size; int room; struct pos_rec **array; }

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

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

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 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; }