/media/sda-magnetic/david/Dokumente-15/fernuni-hagen/cs-i-ii/old-cs-2-03/pascal-compiler/pascal-compiler-2020-03-30-works/pascal151-meilenstein.c


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define NAME_N_MAX 128

/************************* Lexer ************************/

#define DB 1
#define DW 2
#define DD 4
#define DQ 8
#define DT 10

#define TYPE_INTEGER    0
#define TYPE_CHAR       1
#define TYPE_BOOLEAN    2
#define TYPE_REAL       3
#define TYPE_STRING     4

#define NO_TYPE                    -1
#define STD_SIMPLE_TYPE             0
#define ENUM_TYPE                   1
#define SUBRANGE_TYPE               2
#define ARRAY_TYPE                  3
#define RECORD_TYPE                 4
#define PTR_TYPE                    5
#define SELF_DEF_TYPE               6

#define STD_SIMPLE_TYPE_INTEGER     7
#define STD_SIMPLE_TYPE_CHAR        8
#define STD_SIMPLE_TYPE_BOOLEAN     9
#define STD_SIMPLE_TYPE_REAL       10
#define STD_SIMPLE_TYPE_STRING     11

#define GLOBAL_RECORD_TYPE_STACK_PTR_LIMIT  32

char *type_names[] = {"no type", "standard simple type",  "enum type", "subrange type", "array type", "record type", "pointer type", "self defined type", "integer", "char", "boolean", "real", "string"};

struct type {
    int type_id;
    struct std_simple_type *std_simple_type;
    struct enum_type *enum_type;
    struct subrange_type *subrange_type;
    struct array_type *array_type;
    struct record_type *record_type;
    struct ptr_type *ptr_type;
    struct self_def_type *self_def_type;
};


struct std_simple_type {
    int std_simple_type_id;
};

struct enum_type {
    char value[64];
    struct enum_type *next;
};

struct subrange_type {
    char min[64];
    char max[64];
};

struct index_type {
    struct type *index_type;
    struct index_type *next_index;
};

struct array_type {
    struct type *type;
    struct index_type *index;
};

struct record_type {
    struct type *type;
    struct record_type *next;
};

struct ptr_type {
    
};

struct self_def_type {
    char typename[64];
};

struct std_simple_type global_std_simple_type;
struct enum_type *global_enum_type;
struct subrange_type global_subrange_type;
struct array_type *global_array_type;
struct self_def_type global_self_def_type;
struct record_type *global_record_type_stack[GLOBAL_RECORD_TYPE_STACK_PTR_LIMIT];
int global_record_type_stack_ptr = 0;

void push_global_record_type_stack(struct record_type *x) {
    if ((global_record_type_stack_ptr + 1) == (GLOBAL_RECORD_TYPE_STACK_PTR_LIMIT + 1)) {
        perror("record too deeple nested");
        exit(1);
    }
    global_record_type_stack[global_record_type_stack_ptr] = x;
    global_record_type_stack_ptr++;
}

struct record_type *pop_global_record_type_stack(void) {
    
    if(global_record_type_stack == 0) {
        perror("Stack Ptr under limit");
        exit(1);
    }
    global_record_type_stack_ptr--;
    
    return global_record_type_stack[global_record_type_stack_ptr];
}

int namespace_id = 0;

char name_table[NAME_N_MAX][64];
struct type type_table[NAME_N_MAX];

void init_type_table(void) {
    int i;
    
    global_enum_type = NULL;
    global_array_type = NULL;
    
    for (i = 0;  i < NAME_N_MAX;  i++) {
        type_table[i].type_id = NO_TYPE;
        type_table[i].std_simple_type = NULL;
        type_table[i].enum_type = NULL;
        type_table[i].subrange_type = NULL;
        type_table[i].array_type = NULL;
        type_table[i].record_type = NULL;
        type_table[i].ptr_type = NULL;
        
    }
    
    for (i = 0;  i < GLOBAL_RECORD_TYPE_STACK_PTR_LIMIT;  i++)
        global_record_type_stack[i] = NULL;
}

int is_while(char *);
int is_for(char *);
int is_if(char *);
int is_do(char *);
int is_then(char *);
int is_begin(char *);
int is_end(char*);
int while_loop(void);
int if_cond(void);

char buf[1024*1024];
char tmp_str[256];
int  buf_i;
int  buf_len;

int while_label_count = 0;
int for_label_count = 0;
int if_label_count = 0;
int cmp_label_count = 0;
int cmp_end_label_count = 0;
int str_array_stack_ptr = 0;
char str_array[128][128];

struct var_bin_tree *proceduredefinition(void);
struct var_bin_tree *definition_part(void);
struct var_bin_tree *vardefinition(void);

int selfdefinedtype(void);

void push_str(char *str) {
    strcpy(str_array[str_array_stack_ptr], str);
    str_array_stack_ptr++;
return;
}

void pop_str(char *str) {
    str_array_stack_ptr--;
    strcpy(str, str_array[str_array_stack_ptr]);
return;
}

void strincpy(char *des, char *src, int start, int end) {
    int i;
    int j;
    
    for(i = start, j = 0;  i < end;  i++, j++)
        des[j] = src[i];
    des[j] = 0;
return;
}

void get_buf(FILE *fp) {
    int i;
    i = 0;
    while(!feof(fp)) {
        buf[i] = fgetc(fp);
        i++;
    }
    buf_len = i - 1;
return;
}

int lex_get_token_from_stream(char *str) {
    int i;
    int ch;
    
    if(buf_i == buf_len)
        return 0;
    
    ch = buf[buf_i];
    i = 0;

    if ((((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) || (ch == '_')) && ((buf_i + i ) < buf_len)) {
        str[i] = ch;
        i++;
        ch = buf[buf_i + i];
        while ((((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) || (ch == '_')) && ((buf_i + i) < buf_len)) {
            str[i] = ch;
            i++;
            ch = buf[buf_i + i];
        }
        str[i] = 0;
    }
    else if ((ch >= '0') && (ch <= '9') && ((buf_i + i ) < buf_len)) {
        str[i] = ch;
        i++;
        ch = buf[buf_i + i];
        while ((ch >= '0') && (ch <= '9') && ((buf_i + i ) < buf_len)) {
            str[i] = ch;
            i++;
            ch = buf[buf_i + i];
        }
        str[i] = 0;
    }
    else if(ch == '=') {
        str[i] = ch;
        i++;
        ch = buf[buf_i + i];
        if(ch == '=')  {
            str[i] = ch;
            i++;
        }
        str[i] = 0;
    }
    else if(ch == '!') {
        str[i] = ch;
        i++;
        ch = buf[buf_i + i];
        if(ch == '=')  {
            str[i] = ch;
            i++;
        }
        str[i] = 0;
    }
    else if(ch == '<') {
        str[i] = ch;
        i++;
        ch = buf[buf_i + i];
        if(ch == '=')  {
            str[i] = ch;
            i++;
        }
        str[i] = 0;
    }
    else if(ch == '>') {
        str[i] = ch;
        i++;
        ch = buf[buf_i + i];
        if(ch == '=')  {
            str[i] = ch;
            i++;
        }
        str[i] = 0;
    }
    else if(ch == ':') {
        str[i] = ch;
        i++;
        ch = buf[buf_i + i];
        if(ch == '=')  {
            str[i] = ch;
            i++;
        }
        str[i] = 0;
    }
    else if(ch == '.') {
        str[i] = ch;
        i++;
        ch = buf[buf_i + 1];
        if(ch == '.') {
            str[i] = ch;
            i++;
        }
        str[i] = 0;
    }
    else {
        str[i] = ch;
        i++;
        str[i] = 0;
    }
    return i;
}

int lex_get_token_from_stream_ws(char *str) {
    int i;
    
    i = lex_get_token_from_stream(str);
    while (((str[0] == '\n') || (str[0] == '\t') || (str[0] == '\r') || (str[0] == ' ')) && ((buf_i + i) < buf_len)) {
        buf_i += i;
        i = lex_get_token_from_stream(str);
        if(i == 0)
            return 0;
    }
return i;
}

/* parser */

int is_integer(char *str);
int expression(void);
int factor(void);
int term(void);
int statement(void);

void error(void) {
    printf("Bad expression\n");
}

int is_opening_round_bracket(char *str) {return ((str[0] == '(') && (str[1] == 0));}
int is_close_round_bracket(char *str) {return ((str[0] == ')') && (str[1] == 0));}
int is_plus_operator(char *str) {return ((str[0] == '+') && (str[1] == 0));}
int is_minus_operator(char *str) {return ((str[0] == '-') && (str[1] == 0));}
int is_multiplication_operator(char *str) {return ((str[0] == '*') && (str[1] == 0));}
int is_div_operator(char *str) {return ((str[0] == 'd') && (str[1] == 'i') && (str[2] == 'v') && (str[3] == 0));}
int is_mod_operator(char *str) {return ((str[0] == 'm') && (str[1] == 'o') && (str[2] == 'd') && (str[3] == 0));}
int is_and_operator(char *str) {return ((str[0] == 'a') && (str[1] == 'n') && (str[2] == 'd') && (str[3] == 0));}
int is_or_operator(char *str) {return ((str[0] == 'o') && (str[1] == 'r') && (str[2] == 0));}
int is_not_operator(char *str) {return ((str[0] == 'n') && (str[1] == 'o') && (str[2] == 't') && (str[3] == 0));}

int expression_stop(char *str) {
    if((str[0] != '(') && (str[0] != ')') && (str[0] != '*') && (str[0] != '+') && !((str[0] >= '0') && (str[0] <= '9'))) {
        if((str[0] >= 'a') && (str[0] <= 'z')) {
           if(strcmp(str, "end") == 0)
               return 0;
           else if(strcmp(str, "begin") == 0)
               return 0;
           else if(strcmp(str, "for") == 0)
               return 0;
           else if(strcmp(str, "to") == 0)
               return 0;
           else if(strcmp(str, "do") == 0)
               return 0;
           else if(strcmp(str, "while") == 0)
               return 0;
           else if(strcmp(str, "if") == 0)
               return 0;
           else if(strcmp(str, "else") == 0)
               return 0;
           else if(strcmp(str, "program") == 0)
               return 0;
           else if(strcmp(str, "function") == 0)
               return 0;
           else if(strcmp(str, "procedure") == 0)
               return 0;
           else return 1;
        }
        return 0;
    }
return 1;
}

int is_var_name(char *str) {
    int flag = 1;
    int i;
    
    if(!expression_stop(str))
        return 0;

    for(i = 0;  str[i] != 0;  i++)
        if(!((str[i] >= 'a') && (str[i] <= 'z')))
            if(!((str[i] >= 'A') && (str[i] <= 'Z')))
                flag = 0;

return flag;
}

int is_number(char *str) {return is_integer(str);}

int is_integer(char *str) {
    int flag = 1;
    int i;
        
    for(i = 0;  str[i] != 0;  i++)
        if(!((str[i] >= '0') && (str[i] <= '9')))
            flag = 0;
return flag;
}


int is_comma(char *);
  
int function_call_parameters(void) {
    char str[256];
    int buf_j;
    int retv = 0;
    int buf_i_start;
    
    buf_i_start = buf_i;
    
    if(retv = expression()) {
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_comma(str)) {
            buf_i += buf_j;
            retv = (retv && function_call_parameters());
        }
        else
            return 1;
    }
    else {
        buf_i = buf_i_start;
        retv = 0;
    }
return retv;
}

int function_call(void) {
    /* <functioncall> ::= <name> '(' <name1> ',' <name2>, ',' ... ')'*/
    /* <functioncall> ::= <name> '(' <expr1()> ',' <expr2()>, ',' ... ')'*/
    
    char str[256];
    int buf_j;
    int buf_i_start;
    
    buf_i_start = buf_i;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_var_name(str)) {
        buf_i += buf_j;
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_opening_round_bracket(str)) {
            buf_i += buf_j;
            if(function_call_parameters()) {
                buf_j = lex_get_token_from_stream_ws(str);
                if(is_close_round_bracket(str)) {
                    buf_i += buf_j;
                    return 1;
                }
                else {
                    buf_i = buf_i_start;
                    return 0;
                }
            }
            else {
                buf_i = buf_i_start;
                return 0;
            }
        }
        else {
            buf_i = buf_i_start;
            return 0;
        }
    }
    else {
        buf_i = buf_i_start;
        return 0;
    }            
}
        

int procedure_call(void) {
    
    char str[256];
    int buf_j;
    int buf_i_start;
    
    buf_i_start = buf_i;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_var_name(str)) {
        buf_i += buf_j;
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_opening_round_bracket(str)) {
            buf_i += buf_j;
            if(function_call_parameters()) {
                buf_j = lex_get_token_from_stream_ws(str);
                if(is_close_round_bracket(str)) {
                    buf_i += buf_j;
                    return 1;
                }
                else {
                    buf_i = buf_i_start;
                    return 0;
                }
            }
            else {
                buf_i = buf_i_start;
                return 0;
            }
        }
        else {
            buf_i = buf_i_start;
            return 0;
        }
    }
    else {
        buf_i = buf_i_start;
        return 0;
    }     
}

int expr_next_var_name_i = 1;

void expr_get_prev_var_name(char *str) {
    sprintf(str, "x%i", expr_next_var_name_i-1);
return;
}

void expr_get_next_var_name(char *str) {
    sprintf(str, "x%i", expr_next_var_name_i);
    expr_next_var_name_i++;
return;
}

int is_cmp(char *str) {return (((str[0] == '<') && (str[1] == 0)) || \
                               ((str[0] == '>') && (str[1] == 0)) || \
                               ((str[0] == '=') && (str[1] == '=') && (str[2] == 0)) || \
                               ((str[0] == '<') && (str[1] == '=') && (str[2] == 0)) || \
                               ((str[0] == '>') && (str[1] == '=') && (str[2] == 0)) || \
                               ((str[0] == '!') && (str[1] == '=') && (str[2] == 0)));}

#define IS_L  0
#define IS_G  1
#define IS_E  2
#define IS_LE 3
#define IS_GE 4
#define IS_NE 5
                               
int what_cmp(char *str) {
    if((str[0] == '<') && (str[1] == 0))
        return IS_L;
    else if((str[0] == '>') && (str[1] == 0))
        return IS_G;
    else if((str[0] == '=') && (str[1] == '=') && (str[2] == 0))
        return IS_E;
    else if ((str[0] == '<') && (str[1] == '=') && (str[2] == 0)) 
        return IS_LE;
    else if ((str[0] == '>') && (str[1] == '=') && (str[2] == 0)) 
        return IS_GE;
    else if ((str[0] == '!') && (str[1] == '=') && (str[2] == 0))
        return IS_NE;
return -1;
}
                               
                               
int product(void);
int sum(void);



int and(void) {
    int buf_j;
    int retval = 1;
    char tmp_str2[128];
    char tmp_str3[128];
    char tmp_str4[128];
    int tmp_what_cmp;
    
    retval = factor();
    buf_j = lex_get_token_from_stream_ws(tmp_str);
    if(is_and_operator(tmp_str)) {
        pop_str(tmp_str3);
        buf_i += buf_j;
        pop_str(tmp_str2);
        retval = retval && and();
        pop_str(tmp_str3);
        expr_get_next_var_name(tmp_str4);
        printf("and %s, %s, %s\n", tmp_str4, tmp_str2, tmp_str3);
        push_str(tmp_str4);

    }
return retval;
}

int or(void) {
    int buf_j;
    int retval = 1;
    char tmp_str2[128];
    char tmp_str3[128];
    char tmp_str4[128];
    int tmp_what_cmp;
    
    retval = and();
    buf_j = lex_get_token_from_stream_ws(tmp_str);
    if(is_or_operator(tmp_str)) {
        pop_str(tmp_str3);
        buf_i += buf_j;
        pop_str(tmp_str2);
        retval = retval && or();
        pop_str(tmp_str3);
        expr_get_next_var_name(tmp_str4);
        printf("or %s, %s, %s\n", tmp_str4, tmp_str2, tmp_str3);
        push_str(tmp_str4);

    }
return retval;
}

int cmp(void) {
    int buf_j;
    int retval = 1;
    char tmp_str2[128];
    char tmp_str3[128];
    char tmp_str4[128];
    int tmp_what_cmp;
    
    retval = or();
    buf_j = lex_get_token_from_stream_ws(tmp_str);
    if(is_cmp(tmp_str)) {
        tmp_what_cmp = what_cmp(tmp_str);
        buf_i += buf_j;
        pop_str(tmp_str2);
        retval = retval && cmp();
        pop_str(tmp_str3);
        printf("cmp %s, %s\n", tmp_str2, tmp_str3);
        if (tmp_what_cmp == IS_L)
            printf("jl cmp_label%i\n", cmp_label_count);
        else if (tmp_what_cmp == IS_LE)
            printf("jle cmp_label%i\n", cmp_label_count);
        else if (tmp_what_cmp == IS_G)
            printf("jg cmp_label%i\n", cmp_label_count);
        else if (tmp_what_cmp == IS_GE)
            printf("jge cmp_label%i\n", cmp_label_count);
        else if (tmp_what_cmp == IS_E)
            printf("je cmp_label%i\n", cmp_label_count);
        else if (tmp_what_cmp == IS_NE)
            printf("jne cmp_label%i\n", cmp_label_count);
        printf("jmp cmp_end_label%i\n", cmp_end_label_count);
        printf("cmp_label%i:\n", cmp_label_count);
        cmp_label_count++;
    }
return retval;
}

int sum(void) {
    int buf_j;
    int retval = 1;
    char tmp_str2[128];
    char tmp_str3[128];
    char tmp_str4[128];
    
    retval = product();
    buf_j = lex_get_token_from_stream_ws(tmp_str);
    if(is_plus_operator(tmp_str)) {
        buf_i += buf_j;
        pop_str(tmp_str2);
        retval = retval && sum();
        pop_str(tmp_str3);
        expr_get_next_var_name(tmp_str4);
        printf("add %s, %s, %s\n", tmp_str4, tmp_str2, tmp_str3);
        push_str(tmp_str4);
    }
    if(is_minus_operator(tmp_str)) {
        buf_i += buf_j;
        pop_str(tmp_str2);
        retval = retval && sum();
        pop_str(tmp_str3);
        expr_get_next_var_name(tmp_str4);
        printf("sub %s, %s, %s\n", tmp_str4, tmp_str2, tmp_str3);
        push_str(tmp_str4);
    }

return retval;
}

int product(void) {
    int buf_j;
    int retval = 1;
    char tmp_str2[128];
    char tmp_str3[128];
    char tmp_str4[128];
    
    retval = cmp();
    buf_j = lex_get_token_from_stream_ws(tmp_str);
    if(is_multiplication_operator(tmp_str)) {
        buf_i += buf_j;
        pop_str(tmp_str2);
        retval = retval && product();
        pop_str(tmp_str3);
        expr_get_next_var_name(tmp_str4);
        printf("mul %s, %s, %s\n", tmp_str4, tmp_str2, tmp_str3);
        push_str(tmp_str4);
    }
    else if(is_div_operator(tmp_str)) {
        buf_i += buf_j;
        pop_str(tmp_str2);
        retval = retval && product();
        pop_str(tmp_str3);
        expr_get_next_var_name(tmp_str4);
        printf("div %s, %s, %s\n", tmp_str4, tmp_str2, tmp_str3);
        push_str(tmp_str4);
    }
    else if(is_mod_operator(tmp_str)) {
        buf_i += buf_j;
        pop_str(tmp_str2);
        retval = retval && product();
        pop_str(tmp_str3);
        expr_get_next_var_name(tmp_str4);
        printf("mod %s, %s, %s\n", tmp_str4, tmp_str2, tmp_str3);
        push_str(tmp_str4);
    }

return retval;
}


int factor(void) {
    int buf_j;
    int retval = 1;

    buf_j = lex_get_token_from_stream_ws(tmp_str);
    if(is_opening_round_bracket(tmp_str)) {
        buf_i += buf_j;
        sum();
        if(is_close_round_bracket(tmp_str)) {
            buf_i += buf_j;
            retval = 1;
        }
        else
            retval = 0;
    }
    else if(function_call()) {
        return 1;
    }
    else if(is_var_name(tmp_str) || is_number(tmp_str)) {
        buf_i += buf_j;
        push_str(tmp_str);
        return 1;
    }

return retval;
}


int factor_cmp(void) {
    int buf_j;
    int retval = 1;

    buf_j = lex_get_token_from_stream_ws(tmp_str);
    if(is_opening_round_bracket(tmp_str)) {
        buf_i += buf_j;
        cmp();
        if(is_close_round_bracket(tmp_str)) {
            buf_i += buf_j;
            retval = 1;
        }
        else
            retval = 0;
    }
    else if(function_call()) {
        return 1;
    }
    else if(is_var_name(tmp_str) || is_number(tmp_str)) {
        buf_i += buf_j;
        push_str(tmp_str);
        return 1;
    }

return retval;
}

int expression() {
    int retval = 1;
    int buf_i_start;
    char tmp_str2[128];
    
    buf_i_start = buf_i;
    if((retval = sum()) == 0) {
        buf_i = buf_i_start;
        return 0;
    }
    else
        return 1;
}

int exprssion_cmp() {
    int retval = 1;
    int buf_i_start;
    char tmp_str2[128];
    
    buf_i_start = buf_i;
    if((retval = cmp()) == 0) {
        buf_i = buf_i_start;
        return 0;
    }
    else {
        cmp_end_label_count++;
        return 1;    
    }
}

int is_set(char *str) {return ((str[0] == ':') && (str[1] == '=') && (str[2] == 0));}

int assignment_statement() {
    char str[256];
    int buf_j;
    int buf_i_start;
    char tmp_str[128];
    
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_var_name(str)) 
        buf_i += buf_j;
    else {
        buf_i = buf_i_start;
        return 0;
    }
    if(expression_stop(str) == 0) {
        buf_i = buf_i_start;
        return 0;
    }
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_set(str))
        buf_i += buf_j;
    else {
        buf_i = buf_i_start;
        return 0;
    }
    if (expression() == 0) {
        buf_i = buf_i_start;
        return 0;
    }
    strincpy(tmp_str, buf, buf_i_start, buf_i);
    printf("%s\n", tmp_str);

return 1;
}

int cmp2() {
    char str[256];
    char str1[256];
    char str2[256];
    int buf_j;
    int buf_j2;
    int buf_i_tmp = buf_i;
    
    
    buf_j = lex_get_token_from_stream_ws(str);
    
    if (expression() == 0) {
        buf_i = buf_i_tmp;
        return 0;
    }
    buf_j = lex_get_token_from_stream_ws(str1);
    buf_j2 = lex_get_token_from_stream_ws(str2);
    if((str1[0] == '<') && (str1[1] == 0))
        buf_i += buf_j;
    else if((str1[0] == '<') && (str1[1] == 0))
        buf_i += buf_j;
    else if((str1[0] == '<') && (str1[1] == 0))
        buf_i += buf_j;
    else if((str1[0] == '!') && (str1[1] == 0) && (str2[0] == '=') && (str2[0] == 0))
        buf_i += (buf_j + buf_j2);
    else if((str1[0] == '<') && (str1[1] == 0) && (str2[0] == '=') && (str2[0] == 0))
        buf_i += (buf_j + buf_j2);
    else if((str1[0] == '>') && (str1[1] == 0) && (str2[0] == '=') && (str2[0] == 0))
        buf_i += (buf_j + buf_j2);
    else if((str1[0] == '=') && (str1[1] == 0) && (str2[0] == '=') && (str2[0] == 0))
        buf_i += (buf_j + buf_j2);
    else {
        buf_i = buf_i_tmp;
        return 0;
    }

    if (expression() == 0) {
        buf_i = buf_i_tmp;
        return 0;
    }

return 1;
}


int is_for(char *str) {return ((str[0] == 'f') && (str[1] == 'o') && (str[2] == 'r') && (str[3] == 0));} 
int is_do(char *str) {return ((str[0] == 'd') && (str[1] == 'o') && (str[2] == 0));}
int is_to(char *str) {return ((str[0] == 't') && (str[1] == 'o') && (str[2] == 0));}

int for_loop(void) {
    char str[256];
    int buf_j;
    int buf_i_start;
    int ret_val;
    char tmp_str[128];
    char tmp_str2[128];
    int tmp_label;
    int tmp_buf_i;
    
    buf_i_start = buf_i;

    buf_j = lex_get_token_from_stream_ws(str);
    if (is_for(str)) {
        buf_i += buf_j;
    }
    else {
        buf_i = buf_i_start;
        return 0;
    }
    tmp_buf_i = buf_i;
    if (assignment_statement() == 0) {
        buf_i = buf_i_start;
        return 0;
    }
    strincpy(tmp_str, buf, tmp_buf_i, buf_i);
    push_str(tmp_str);
    tmp_label = for_label_count;
    printf("label_for_%i:\n", for_label_count++);
    
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_to(str)) 
        buf_i += buf_j;
    else {
        buf_i = buf_i_start;
        return 0;
    }
    tmp_buf_i = buf_i;
    if (expression() == 0) {
        buf_i = buf_i_start;
        return 0;
    }
    strincpy(tmp_str, buf, tmp_buf_i, buf_i);
    push_str(tmp_str);
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_do(str)) 
        buf_i += buf_j;
    else {
        buf_i = buf_i_start;
        return 0;
    }
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_begin(str)) {
        buf_i += buf_j;
        ret_val = statement();
        
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_end(str)) {
            buf_i += buf_j;
            if(ret_val == 0)
                buf_i = buf_i_start;
            
            pop_str(tmp_str);
            pop_str(tmp_str2);
            printf("inc from var in %s\n", tmp_str2);
            printf("cmp %s\n", tmp_str);
            printf("je label_for_%i\n", tmp_label);            
            
            return ret_val;
        }
        else {
            buf_i = buf_i_start;
            return 0;
        }
    }
    else if(is_for(str)) {
        pop_str(tmp_str);
        pop_str(tmp_str2);
        printf("inc from var in %s\n", tmp_str2);
        printf("cmp %s\n", tmp_str);
        printf("je label_for_%i\n", tmp_label);         
        return for_loop();
    }
    else if(is_while(str)) {
        pop_str(tmp_str);
        pop_str(tmp_str2);
        printf("inc from var in %s\n", tmp_str2);
        printf("cmp %s\n", tmp_str);
        printf("je label_for_%i\n", tmp_label);         
        return while_loop();
    }
    else if(is_if(str)) {
        pop_str(tmp_str);
        pop_str(tmp_str2);
        printf("inc from var in %s\n", tmp_str2);
        printf("cmp %s\n", tmp_str);
        printf("je label_for_%i\n", tmp_label);         
        return if_cond();
    }
    else {
        if(assignment_statement()) {
            pop_str(tmp_str);
            pop_str(tmp_str2);
            printf("inc from var in %s\n", tmp_str2);
            printf("cmp %s\n", tmp_str);
            printf("je label_for_%i\n", tmp_label);         
            return 1;
        }
        else {
            buf_i = buf_i_start;
            return 0;
        }
    }
}

int is_while(char *str) {return ((str[0] == 'w') && (str[1] == 'h') && (str[2] == 'i') && (str[3] == 'l') && (str[4] == 'e') && (str[5] == 0));} 

int while_loop(void) {
    char str[256];
    int buf_j;
    int buf_i_start;
    int tmp_buf_i;
    int ret_val;
    char tmp_str[128];
    int tmp_label;
    
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_while(str)) {
        tmp_label = while_label_count;
        printf("label_while_%i:\n", while_label_count++);
        buf_i += buf_j;
    }
    else {
        buf_i = buf_i_start;
        return 0;
    }
    
    tmp_buf_i = buf_i;
    
    if(cmp() == 0) {
        tmp_buf_i = buf_i;
        if(expression() == 0) {
            buf_i = buf_i_start;
            return 0;
        }
        strincpy(tmp_str, buf, tmp_buf_i, buf_i);
    }
    else
        strincpy(tmp_str, buf, tmp_buf_i, buf_i);
    push_str(tmp_str);
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_do(str))
        buf_i += buf_j;
    else {
        buf_i = buf_i_start;
        return 0;
    }
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_begin(str)) {
        buf_i += buf_j;
        
        ret_val = statement();
        
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_end(str)) {
            buf_i += buf_j;
            if(ret_val == 0)
                buf_i = buf_i_start;
            
            pop_str(tmp_str);
            printf("cmp %s\n", tmp_str);
            printf("je label_while_%i\n", tmp_label);
            
            return ret_val;
        }
        else {
            buf_i = buf_i_start;
            return 0;
        }
    }
    else if(is_for(str)) {
        pop_str(tmp_str);
        printf("cmp %s\n", tmp_str);
        printf("je label_while_%i\n", tmp_label);

        return for_loop();
    }
    else if(is_while(str)) {
        pop_str(tmp_str);
        printf("cmp %s\n", tmp_str);
        printf("je label_while_%i\n", tmp_label);

        return while_loop();
    }
    else if(is_if(str)) {
        pop_str(tmp_str);
        printf("cmp %s\n", tmp_str);
        printf("je label_while_%i\n", tmp_label);

        return if_cond();
    }
    else {
        if(assignment_statement()) {
            pop_str(tmp_str);
            printf("cmp %s\n", tmp_str);
            printf("je label_while_%i\n", tmp_label);

            return 1;
        }
        else {
            buf_i = buf_i_start;
            return 0;
        }
    }
}

int is_if(char *str) {return ((str[0] == 'i') && (str[1] == 'f') && (str[2] == 0));}
int is_then(char *str) {return ((str[0] == 't') && (str[1] == 'h') && (str[2] == 'e') && (str[3] == 'n') && (str[4] == 0));}  
int is_else(char *str) {return ((str[0] == 'e') && (str[1] == 'l') && (str[2] == 's') && (str[3] == 'e') && (str[4] == 0));}  
int is_else_if(char *str) {return ((str[0] == 'i') && (str[1] == 'f') && (str[2] == ' ') && (str[3] == 'e') && (str[4] == 'l') && (str[5] == 's')  && (str[6] == 'e') && (str[6] == 0));}  


int if_cond(void) {
    char str[256];
    int buf_j;
    int buf_i_start;
    int ret_val;
    int tmp_buf_i;
    char tmp_str[128];
    int tmp_label;
    
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_if(str))
        buf_i += buf_j;
    else {
        buf_i = buf_i_start;
        return 0;
    }
    tmp_buf_i = buf_i;
    if(cmp() == 0) {
        if(expression() == 0) {
            buf_i = buf_i_start;
            return 0;
        }
        strincpy(tmp_str, buf, tmp_buf_i, buf_i);
    }
    else
        strincpy(tmp_str, buf, tmp_buf_i, buf_i);
    printf("%s\n", tmp_str);
    tmp_label = if_label_count;
    if_label_count++;
    printf("jne if_label_%i\n", tmp_label);
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_then(str))
        buf_i += buf_j;
    else  {
        buf_i = buf_i_start;
        return 0;
    }
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_begin(str)) {
        buf_i += buf_j;
        
        ret_val = statement();
        
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_end(str)) {
            buf_i += buf_j;
            if(ret_val == 0)
               buf_i = buf_i_start;
            printf("if_label_%i:\n", tmp_label);
            return ret_val;
        }
        else {
            buf_i = buf_i_start;
            return 0;
        }
    }
    else if(is_for(str)) {
        printf("if_label_%i:\n", tmp_label);
        return for_loop();
    }
    else if(is_while(str)) {
        printf("if_label_%i:\n", tmp_label);
        return while_loop();
    }
    else if(is_if(str)) {
        printf("if_label_%i:\n", tmp_label);
        return if_cond();
    }
    else {
        if(assignment_statement()) {
            printf("if_label_%i:\n", tmp_label);
            return 1;
        }
        else {
            buf_i = buf_i_start;
            return 0;
        }
    }
}

int if_else_cond(void) {
    char str[256];
    int buf_j;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_else_if(str))
        buf_i += buf_j;
    else
        return 0;
    if(cmp2() == 0)
        if(expression() == 0)
            return 0;
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_then(str))
        buf_i += buf_j;
    else 
        return 0;
return statement();    
}

int else_cond(void) {
    char str[256];
    int buf_j;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_else(str))
        buf_i += buf_j;
    else
        return 0;
    if(cmp2() == 0)
        if(expression() == 0)
            return 0;
    buf_j = lex_get_token_from_stream_ws(str);
return statement();    
}


int is_begin(char *str) {return ((str[0] == 'b') && (str[1] == 'e') && (str[2] == 'g') && (str[3] == 'i') && (str[4] == 'n') && (str[5] == 0));} 
int is_end(char *str) {return ((str[0] == 'e') && (str[1] == 'n') && (str[2] == 'd') && (str[3] == 0));} 
int is_semicolon(char *str) {return ((str[0] == ';') && (str[1] == 0));}
int is_colon(char *str) {return ((str[0] == ':') && (str[1] == 0));}
int is_function(char *str) {return ((str[0] == 'f') && (str[1] == 'u') && (str[2] == 'n') && (str[3] == 'c') && (str[4] == 't') && (str[5] == 'i') && (str[6] == 'o') && (str[7] == 'n') && (str[8] == 0));} 
int is_var_procedure_attribute(char *str) {return ((str[0] == 'v') && (str[1] == 'a') && (str[2] == 'r') && (str[3] == 0));}  
int is_procedure(char *str) {return ((str[0] == 'p') && (str[1] == 'r') && (str[2] == 'o') && (str[3] == 'c') && (str[4] == 'e') && (str[5] == 'd') && (str[6] == 'u') && (str[7] == 'r') && (str[8] == 'e')  && (str[9] == 0));} 
int is_program_keyword(char *str) {return ((str[0] == 'p') && (str[1] == 'r') && (str[2] == 'o') && (str[3] == 'g') && (str[4] == 'r') && (str[5] == 'a') && (str[6] == 'm') && (str[7] == 0));} 
int is_comma(char *str) {return ((str[0] == ',') && (str[1] == 0));}
int is_dot(char *str) {return ((str[0] == '.') && (str[1] == 0));}
int is_two_dot(char *str) {return ((str[0] == '.') && (str[1] == '.') && (str[2] == 0));}
int is_type(char *str) {return ((str[0] == 't') && (str[1] == 'y') && (str[2] == 'p') && (str[3] == 'e') && (str[4] == 0));}  
int is_equal(char *str) {return ((str[0] == '=') && (str[1] == 0));}
int is_record_keyword(char *str) {return ((str[0] == 'r') && (str[1] == 'e') && (str[2] == 'c') && (str[3] == 'o') && (str[4] == 'r') && (str[5] == 'd') && (str[6] == 0));} 


int programparameter(void) {
    char str[256];
    int buf_i_start;
    int buf_j;
    int retval = 1;
    /*
     * 
     * <paramter> ::= id : type 
     * 
     * */
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_var_name(str)) {
        buf_i += buf_j;
        retval = 1;
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
return retval;
}


int parameter(void) {
    char str[256];
    int buf_i_start;
    int buf_j;
    int retval = 1;
    /*
     * 
     * <paramter> ::= id : type 
     * 
     * */
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_var_name(str)) {
        buf_i += buf_j;
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_colon(str)) {
            buf_i += buf_j;
            buf_j = lex_get_token_from_stream_ws(str);
            if(is_var_name(str)) {
                buf_i += buf_j;
                retval = 1;
            }
            else {
                buf_i = buf_i_start;
                retval = 0;
            }
        }
        else {
            buf_i = buf_i_start;
            retval = 0;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
return retval;
}

int varparameter(void) {
    char str[256];
    int buf_i_start;
    int buf_j;
    int retval = 1;
    /*
     * 
     * <paramter> ::= id : type 
     * 
     * */
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_var_procedure_attribute(str)) {
        buf_i += buf_j;
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_var_name(str)) {
            buf_i += buf_j;
            buf_j = lex_get_token_from_stream_ws(str);
            if(is_colon(str)) {
                buf_i += buf_j;
                buf_j = lex_get_token_from_stream_ws(str);
                if(is_var_name(str)) {
                    buf_i += buf_j;
                    retval = 1;
                }
                else {
                    buf_i = buf_i_start;
                    retval = 0;
                }
            }
            else {
                buf_i = buf_i_start;
                retval = 0;
            }
        }
        else {
            buf_i = buf_i_start;
            retval = 0;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
return retval;
}



int parameterlist(void) {
    int buf_i_start;
    int buf_i_start2;
    int retval = 1;
    char str[256];
    int buf_j;
    /*
     * 
     * <parameterlist> ::= <parameter> | <parameter> <parameterlist>
     * 
     * 
     * */
    
    buf_i_start = buf_i;
    if(retval = parameter()) {
        buf_j = lex_get_token_from_stream_ws(str);
        buf_i_start2 = buf_i;
        if(is_semicolon(str)) {
            buf_i += buf_j;
            parameterlist();
        }
        else 
            buf_i = buf_i_start2;
    }
    if(retval == 0) 
        buf_i_start = buf_i;
return retval;
}


int procedureparameterlist(void) {
    int buf_i_start;
    int buf_i_start2;
    int retval = 1;
    char str[256];
    int buf_j;
    /*
     * 
     * <parameterlist> ::= <parameter> | <parameter> <parameterlist>
     * 
     * 
     * */
    
    buf_i_start = buf_i;
    retval = parameter() | varparameter();
    if(retval) {
        buf_j = lex_get_token_from_stream_ws(str);
        buf_i_start2 = buf_i;
        if(is_semicolon(str)) {
            buf_i += buf_j;
            procedureparameterlist();
        }
        else 
            buf_i = buf_i_start2;
    }
    if(retval == 0) 
        buf_i_start = buf_i;
return retval;
}

int programparameterlist(void) {
    int buf_i_start;
    int buf_i_start2;
    int retval = 1;
    char str[256];
    int buf_j;
    /*
     * 
     * <parameterlist> ::= <parameter> | <parameter> <parameterlist>
     * 
     * 
     * */
    
    buf_i_start = buf_i;
    retval = programparameter();
    if(retval) {
        buf_j = lex_get_token_from_stream_ws(str);
        buf_i_start2 = buf_i;
        if(is_comma(str)) {
            buf_i += buf_j;
            programparameterlist();
        }
        else 
            buf_i = buf_i_start2;
    }
    if(retval == 0) 
        buf_i_start = buf_i;
return retval;
}


int parameter_list(void) {
    char str[256];
    int buf_i_start;
    int retval = 1;
    int buf_j;

    /* 
     * parameter_list ::= ( parameterlist )
     * 
     */
    
    buf_i_start = buf_i;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_opening_round_bracket(str)) {
        buf_i += buf_j;
        retval = parameterlist();
        if(retval == 0) {
            buf_i = buf_i_start;
            return 0;
        }
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_close_round_bracket(str)) {
            buf_i += buf_j;
            return 1;
        }
        else {
            buf_i = buf_i_start;
            return 0;
        }
    }
    else {
        retval = 0;
        buf_i = buf_i_start;
    }
        
return retval;
}


int procedure_parameter_list(void) {
    char str[256];
    int buf_i_start;
    int retval = 1;
    int buf_j;

    /* 
     * parameter_list ::= ( parameterlist )
     * 
     */
    
    buf_i_start = buf_i;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_opening_round_bracket(str)) {
        buf_i += buf_j;
        retval = procedureparameterlist();
        if(retval == 0) {
            buf_i = buf_i_start;
            return 0;
        }
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_close_round_bracket(str)) {
            buf_i += buf_j;
            return 1;
        }
        else {
            buf_i = buf_i_start;
            return 0;
        }
    }
    else {
        retval = 0;
        buf_i = buf_i_start;
    }
        
return retval;
}

int program_parameter_list(void) {
    char str[256];
    int buf_i_start;
    int retval = 1;
    int buf_j;

    /* 
     * parameter_list ::= ( parameterlist )
     * 
     */
    
    buf_i_start = buf_i;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_opening_round_bracket(str)) {
        buf_i += buf_j;
        retval = programparameterlist();
        if(retval == 0) {
            buf_i = buf_i_start;
            return 0;
        }
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_close_round_bracket(str)) {
            buf_i += buf_j;
            buf_j = lex_get_token_from_stream_ws(str);
            if(is_semicolon(str)) {
                buf_i += buf_j;
                return 1;
            }
            else {
                buf_i = buf_i_start;
                return 0;
            }
        }
        else {
            buf_i = buf_i_start;
            return 0;
        }
    }
    else {
        retval = 0;
        buf_i = buf_i_start;
    }
        
return retval;
}

int func_type_set(char *);

int result_type(void) {
    char str[256];
    int buf_i_start;
    int retval = 1;
    int buf_j;

    
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_var_name(str)) {
        buf_i += buf_j;
        if(func_type_set(str)) 
            retval = 1;
        else {
            retval = 0;
            buf_i = buf_i_start;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
return retval;
}
    


    
int func_type_set(char *str) {
    return 1;
}

  
    
int block(void) {
    char str[256];
    int retval = 1;
    int buf_i_start;
    int buf_j;
    
    buf_i_start = buf_i;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_begin(str)) {
        buf_i += buf_j;
        retval = statement();
        if(retval != 0) {
            buf_j = lex_get_token_from_stream_ws(str);
            if(is_end(str)) {
                buf_i += buf_j;
                buf_j = lex_get_token_from_stream_ws(str);
                if(is_semicolon(str)) {
                    buf_i += buf_j;
                    retval = 1;
                }
                else {
                    buf_i = buf_i_start;
                    retval = 0;
                }
            }
        }
        else 
            buf_i = buf_i_start;
    }
    else {
        retval = 0;
        buf_i = buf_i_start;
    }
return retval;
}




int functioncall(void) {
    
}

int emptystatement() {
    return 1;
}

int emptystatement2() {
    int buf_j;
    char str[256];
    
    buf_j = lex_get_token_from_stream_ws(str);
    
    if(is_semicolon(str)) {
        buf_i += buf_j;
        return 1;
    }
return 0;
}

int statement(void) {
    char str[256];
    int buf_j;
    int retv;
    int buf_i_start;
    
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_begin(str)) {
        buf_i += buf_j;
        retv = statement();
        buf_j = lex_get_token_from_stream_ws(str);
        if(!is_end(str)) {
            buf_i = buf_i_start;
            return 0;
        }
        buf_i += buf_j;
        
        buf_j = lex_get_token_from_stream_ws(str);
        if (is_semicolon(str)) {
           buf_i += buf_j;
           retv = statement();
        }
        if(retv == 0)
            buf_i = buf_i_start;
        return retv;
    }
    if (for_loop()) retv = 1;
    else if (while_loop()) retv = 1;
    else if (if_cond()) retv = 1;
    else if (assignment_statement()) retv = 1;
    else if (function_call()) retv = 1;
    else if (procedure_call()) retv = 1;
    else if (emptystatement2()) retv = 1;
    else {
        buf_i = buf_i_start;
        return 0;
    }
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_semicolon(str)) {
        buf_i += buf_j;
        retv = statement() || emptystatement();
    }
    if(retv == 0)
        buf_i = buf_i_start;

return retv;
}    

int program_heading(void) {
    int retval = 1;
    int buf_i_start;
    char str[256];
    int buf_j;
    
    buf_i_start = buf_i;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_program_keyword(str)) {
        buf_i += buf_j;
        buf_j = lex_get_token_from_stream_ws(str); 
        if(is_var_name(str)) {
            buf_i += buf_j;
            if(program_parameter_list()) {
                if(func_type_set("procedure") != 0) {
                    retval = 1;
                }
                else {
                    buf_i = buf_i_start;
                    retval = 0;
                }
            }
            else {
                buf_i = buf_i_start;
                retval = 0;
            }
        }
        else {
            buf_i = buf_i_start;
            retval = 0;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
return retval;
}

struct var_bin_tree {
    struct var_bin_tree *next;
    struct var_bin_tree *sub;
    int id;
    int type_id;
};

struct type_bin_tree {
    struct type_bin_tree *next;
    struct type_bin_tree *sub;
    int type_id;
    int loop;
};


struct var_bin_tree *ptr;

void printtree(struct var_bin_tree *ptr) {
    if(ptr != NULL) {
        printtree(ptr->next);
        printf("<li>\n");
        printf("%i %s\n", ptr->id, name_table[ptr->id]);
        printf("</li>\n");
        printf("<ul>\n");
        printtree(ptr->sub);
        printf("</ul>\n");
        
    }
}


int program(void) {
    int retval = 1;
    int buf_i_start;
    char str[256];
    int buf_j;
    
    buf_i_start = buf_i;
    
    
    if(program_heading()) {
        retval = 1;     
   
        ptr = definition_part();
        
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_begin(str)) {
            buf_i += buf_j;
            retval = (retval && statement());
            buf_j = lex_get_token_from_stream_ws(str);
            if(is_end(str)) {
                buf_i += buf_j;
                buf_j = lex_get_token_from_stream_ws(str);
                if(is_dot(str)) {
                    buf_i += buf_j;
                    retval = (retval && 1);
                }
                else {
                    buf_i = buf_i_start;
                    retval = 0;
                }
            }
            else {
                retval = 0;
                buf_i = buf_i_start;
            }
        }
        else {
            buf_i = buf_i_start;
            retval = 0;
        }
    }
    else {
        retval = 0;
        buf_i = buf_i_start;
    }

return retval;
}






struct var_bin_tree *root;
    
int create_name(char *str) {
    namespace_id++;
    if(namespace_id < NAME_N_MAX)
        strcpy(name_table[namespace_id], str);
    else {
        printf("I'm sorry too much names in use\n");
        return 0;
    }
return 1;
}


int functionheading(void) {
    char str[256];
    int buf_i_start;
    int retval = 1;    
    int buf_j;
    
    /*
     * <functionsheading> ::= function <functionid> <parameterlist> : <resulttype>;
     */
    
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_function(str)) {
        buf_i += buf_j;
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_var_name(str)) {
            
            /* So an dieser Stelle muss die Tabelle fuer die Namen her */
            
            if(create_name(str) != 0) {
                buf_i += buf_j;
                if(parameter_list()) {
                    buf_j = lex_get_token_from_stream_ws(str);
                    if(is_colon(str)) {
                        buf_i += buf_j;
                        if(result_type()) {
                            buf_j = lex_get_token_from_stream_ws(str);
                            if(is_semicolon(str)) {
                                retval = 1;
                                buf_i += buf_j;
                            }
                            else {
                                retval = 0;
                                buf_i = buf_i_start;
                            }
                        }
                        else {
                            retval = 0;
                            buf_i = buf_i_start;
                        }
                    }
                    else {
                        retval = 0;
                        buf_i = buf_i_start;
                    }
                }
                else {
                    retval = 0;
                    buf_i = buf_i_start;
                }
            }
            else {
                retval = 0;
                buf_i = buf_i_start;
            }
        }
        else {
            retval = 0;
            buf_i = buf_i_start;
        }
    }
    else {
        retval = 0;
        buf_i = buf_i_start;
    }
    
return retval;
}
    

int procedureheading(void) {
    char str[256];
    int buf_i_start;
    int retval = 1;    
    int buf_j;
    
    /*
     * <procedureheading> ::= procedure <procedureid> <procedureparameterlist>;
     */
    
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_procedure(str)) {
        buf_i += buf_j;
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_var_name(str)) {
             if(create_name(str) != 0) {
                buf_i += buf_j;
                if(procedure_parameter_list()) {
                    if(func_type_set("procedure") != 0) {
                        buf_j = lex_get_token_from_stream_ws(str);
                        if(is_semicolon(str)) {
                            retval = 1;
                            buf_i += buf_j;
                        }
                        else {
                            retval = 0;
                            buf_i += buf_j;
                        }
                    }
                    else {
                        retval = 0;
                        buf_i = buf_i_start;
                    }
                }
                else {
                    retval = 0;
                    buf_i = buf_i_start;
                }
            }
            else {
                retval = 0;
                buf_i = buf_i_start;
            }
        }
        else {
            retval = 0;
            buf_i = buf_i_start;
        }
    }
    else {
        retval = 0;
        buf_i = buf_i_start;
    }
    
return retval;
}
  
    
int is_var_type(void);
int vartypestring(void);

struct var_bin_tree *functiondefinition(void) {
    int buf_i_start;
    int retv;
    struct var_bin_tree *retval;
        
    buf_i_start = buf_i;
    
    retv = functionheading();
    if(retv == 0) {
        buf_i = buf_i_start; 
    }
    else {
        if((retval = (struct var_bin_tree *)malloc(sizeof(struct var_bin_tree))) == NULL) {
            perror("Not enough memory");
            exit(1);
        }
        retval->id = namespace_id;
        retval->next = NULL;
        retval->sub = definition_part();
        
        retv = block();
        if(retv == 0)
            buf_i = buf_i_start;
    }
    
return retval;
}


struct var_bin_tree *type_definition(void);
    
struct var_bin_tree *definition_part(void) {
    struct var_bin_tree *retval = NULL;
            
    if((retval = vardefinition()) != NULL)
        retval->next = definition_part();
    else if((retval = functiondefinition()) != NULL)
        retval->next = definition_part();
    else if((retval = proceduredefinition()) != NULL)
        retval->next = definition_part();
    else if((retval = type_definition()) != NULL) 
        retval->next = definition_part();

return retval;
}


struct var_bin_tree *proceduredefinition(void) {
    int buf_i_start;
    int retv;
    struct var_bin_tree *retval;
        
    buf_i_start = buf_i;
    
    retv = procedureheading();
    if(retv == 0) {
        buf_i = buf_i_start; 
    }
    else {
        if((retval = (struct var_bin_tree *)malloc(sizeof(struct var_bin_tree))) == NULL) {
            perror("Not enough memory");
            exit(1);
        }
        retval->id = namespace_id;
        retval->next = NULL;
        retval->sub = definition_part();
        
        retv = block();
        if(retv == 0)
            buf_i = buf_i_start;
    }
    
return retval;
}


int var_type_set(char *str) {
    return 1;
}


struct var_bin_tree *vardefinition(void) {
    int buf_i_start;
    int buf_j;
    struct var_bin_tree *retval;
    char str[256];
    
    buf_i_start = buf_i;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_var_procedure_attribute(str)) {
        buf_i += buf_j;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_var_name(str)) {
        if(create_name(str) != 0) {
            buf_i += buf_j;
            buf_j = lex_get_token_from_stream_ws(str);
            if(is_colon(str)) {
                buf_i += buf_j;
                if(is_var_type()) {
                    if(var_type_set(str)) {
                       // buf_j = lex_get_token_from_stream_ws(str);
                       // if(is_semicolon(str)) {
                            buf_i += buf_j;
                            if((retval = (struct var_bin_tree *)malloc(sizeof(struct var_bin_tree))) == NULL) {
                                perror("Not enough memory");
                                exit(1);
                            }
                            retval->next = NULL;
                            retval->sub = NULL;
                            retval->id = namespace_id;
                        //}
                        //else {
                        //    buf_i = buf_i_start;
                        //    retval = NULL;
                        //}
                    }
                    else {
                        buf_i = buf_i_start;
                        retval = NULL;
                    }
                }
                else {
                    buf_i = buf_i_start;
                    retval = NULL;
                }
            }
            else {
                buf_i = buf_i_start;
                retval = NULL;
            }
        }
        else {
            buf_i = buf_i_start;
            retval = NULL;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = NULL;
    }
    }
      else {
        buf_i = buf_i_start;
        retval = NULL;
      }
    
return retval;
}

int standardsimpletype(void) {
    int buf_i_start;
    int buf_j;
    char str[256];
    int retval = 0;
    
    buf_i_start = buf_i;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if(strcmp(str, "integer") == 0) {
        global_std_simple_type.std_simple_type_id = STD_SIMPLE_TYPE_INTEGER;
        buf_i += buf_j;
        retval = 1;
    }
    else if(strcmp(str, "real") == 0) {
        global_std_simple_type.std_simple_type_id = STD_SIMPLE_TYPE_REAL;
        buf_i += buf_j;
        retval = 1;
    }
    else if(strcmp(str, "boolean") == 0) {
        global_std_simple_type.std_simple_type_id = STD_SIMPLE_TYPE_BOOLEAN;
        buf_i += buf_j;
        retval = 1;
    }
    else if(strcmp(str, "char") == 0) {
        global_std_simple_type.std_simple_type_id = STD_SIMPLE_TYPE_CHAR;
        buf_i += buf_j;
        retval = 1;
    }
    else if(strcmp(str, "string") == 0) {
        global_std_simple_type.std_simple_type_id = STD_SIMPLE_TYPE_STRING;
        buf_i += buf_j;
        retval = 1;
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
return retval;
}

int is_array(char *str) {return ((str[0] == 'a') && (str[1] == 'r') && (str[2] == 'r') && (str[3] == 'a') && (str[4] == 'y') && (str[5] == 0));} 
int is_of(char *str) {return ((str[0] == 'o') && (str[1] == 'f') && (str[2] == 0));} 
int is_opening_square_bracket (char *str) {return ((str[0] == '[') && (str[1] == 0));}
int is_closed_square_bracket (char *str) {return ((str[0] == ']') && (str[1] == 0));}

int enumtype(void);
int subrangetype(void);
int is_var_type(void);

int array_index_chain(struct index_type *p) {
    int buf_i_start;
    int buf_j;
    int retval = 1;
    char str[256];
    
    buf_i_start = buf_i;
    
    buf_j = lex_get_token_from_stream_ws(str);
    
    if((p->index_type = (struct type *)malloc(sizeof(struct type))) == NULL) {
        perror("not enough memory");
        exit(1);
    }    
    if (enumtype()) {
        if((p->index_type->enum_type = (struct enum_type *)malloc(sizeof(struct type))) == NULL) {
            perror("not enough memory");
            exit(1);
        }
        p->index_type->type_id = ENUM_TYPE;
        p->index_type->enum_type = global_enum_type;        
        buf_j = lex_get_token_from_stream_ws(str);
        if (is_comma(str)) {
            buf_i += buf_j;
            if((p->next_index = (struct index_type *)malloc(sizeof(struct index_type))) == NULL) {
                perror("not enough memory");
                exit(1);
            }
            retval = (retval && array_index_chain(p->next_index));
        }
        else {
            retval = 1;
        }
    }
    else if(subrangetype()) {
        if((p->index_type->subrange_type = (struct subrange_type *)malloc(sizeof(struct subrange_type))) == NULL) {
            perror("not enough memory");
            exit(1);
        }
        p->index_type->type_id = SUBRANGE_TYPE;
        (*(p->index_type->subrange_type)) = global_subrange_type;        
        buf_j = lex_get_token_from_stream_ws(str);
        if (is_comma(str)) {
            buf_i += buf_j;
            if((p->next_index = (struct index_type *)malloc(sizeof(struct index_type))) == NULL) {
                perror("not enough memory");
                exit(1);
            }
            retval = (retval && array_index_chain(p->next_index));
        }
        else {
            retval = 1;
        }        
    }
    else if(standardsimpletype()) {
        if((p->index_type->std_simple_type = (struct std_simple_type *)malloc(sizeof(struct std_simple_type))) == NULL) {
            perror("not enough memory");
            exit(1);
        }
        p->index_type->type_id = STD_SIMPLE_TYPE;
        (*(p->index_type->std_simple_type)) = global_std_simple_type;        
        buf_j = lex_get_token_from_stream_ws(str);
        if (is_comma(str)) {
            buf_i += buf_j;
            if((p->next_index = (struct index_type *)malloc(sizeof(struct index_type))) == NULL) {
                perror("not enough memory");
                exit(1);
            }            
            retval = (retval && array_index_chain(p->next_index));
        }
        else {
            retval = 1;
        }        
    }
    else if(selfdefinedtype()){
        if((p->index_type->self_def_type = (struct self_def_type *)malloc(sizeof(struct self_def_type))) == NULL) {
            perror("not enough memory");
            exit(1);
        }
        p->index_type->type_id = SELF_DEF_TYPE;
        (*(p->index_type->self_def_type)) = global_self_def_type;        
        buf_j = lex_get_token_from_stream_ws(str);
        if (is_comma(str)) {
            buf_i += buf_j;
            retval = (retval && array_index_chain(p->next_index));
        }
        else {
            retval = 1;
        }        
    }
    else {
        printf("Index type musst be either an enum type or a subrange type or a standard simple type or a selfdefined type, that fits\n");
        buf_i = buf_i_start;
        retval = 0;
    }
    
return retval;
}


int arraytype(struct array_type *p) {
    int buf_i_start;
    int buf_j;
    int retval = 1;
    char str[256];
    
    buf_i_start = buf_i;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_array(str)) {
        
        if(p == NULL) {
            if((global_array_type = (struct array_type *)malloc(sizeof(struct array_type))) == NULL) {
                perror("Not enough memory");
                exit(1);
            }
            p = global_array_type;
        }
        if((p->type = (struct type *)malloc(sizeof(struct type))) == NULL) {
            perror("Not enough memory");
            exit(1);
        }
        if((p->type->array_type = (struct array_type *)malloc(sizeof(struct array_type))) == NULL) {
            perror("Not enough memory");
            exit(1);
        }
        
        if((p->index = (struct index_type *)malloc(sizeof(struct index_type))) == NULL) {
            perror("Not enough memory");
            exit(1);
        } 
        
        
       buf_i += buf_j; 
       buf_j = lex_get_token_from_stream_ws(str);
       if(is_opening_square_bracket(str)) {
           buf_i += buf_j;
           if (array_index_chain(p->index)) {
               buf_j = lex_get_token_from_stream_ws(str);
               if(is_closed_square_bracket(str)) {
                   buf_i += buf_j;
                   buf_j = lex_get_token_from_stream_ws(str);
                   if(is_of(str)) {
                       buf_i += buf_j;
                       if(standardsimpletype()) {
                           free(p->type->array_type);
                           free(p->type);
                           p->type->array_type = NULL;
                           p->type = NULL;
                           if((p->type = (struct type *)malloc(sizeof(struct type))) == NULL) {
                               perror("Not enough memory");
                               exit(1);
                           }
                           if((p->type->std_simple_type = (struct std_simple_type *)malloc(sizeof(struct std_simple_type))) == NULL) {
                               perror("Not enough memory");
                               exit(1);
                           }
                           p->type->type_id = STD_SIMPLE_TYPE;
                           (*(p->type->std_simple_type)) = global_std_simple_type;
                           retval = 1;
                       }
                       else if(arraytype(p->type->array_type)) {
                           p->type->type_id = ARRAY_TYPE;
                           retval = 1;
                       }
                       else if(subrangetype()) {                           
                           free(p->type->array_type);
                           free(p->type);
                           p->type->array_type = NULL;
                           p->type = NULL;
                           if((p->type = (struct type *)malloc(sizeof(struct type))) == NULL) {
                               perror("Not enough memory");
                               exit(1);
                           }
                           if((p->type->subrange_type = (struct subrange_type *)malloc(sizeof(struct subrange_type))) == NULL) {
                               perror("Not enough memory");
                               exit(1);
                           }
                           p->type->type_id = SUBRANGE_TYPE;
                           (*(p->type->subrange_type)) = global_subrange_type;
                           retval = 1;
                       }
                       else if(enumtype()) {
                           free(p->type->array_type);
                           free(p->type);
                           p->type->array_type = NULL;
                           p->type = NULL;
                           if((p->type = (struct type *)malloc(sizeof(struct type))) == NULL) {
                               perror("Not enough memory");
                               exit(1);
                           }
                           if((p->type->enum_type = (struct enum_type *)malloc(sizeof(struct enum_type))) == NULL) {
                               perror("Not enough memory");
                               exit(1);
                           }
                           p->type->type_id = ENUM_TYPE;
                           p->type->enum_type = global_enum_type;
                           retval = 1;
                       }
                       else if(selfdefinedtype()) {
                           free(p->type->array_type);
                           free(p->type);
                           p->type->array_type = NULL;
                           p->type = NULL;
                           if((p->type = (struct type *)malloc(sizeof(struct type))) == NULL) {
                               perror("Not enough memory");
                               exit(1);
                           }
                           if((p->type->self_def_type = (struct self_def_type *)malloc(sizeof(struct self_def_type))) == NULL) {
                               perror("Not enough memory");
                               exit(1);
                           }
                           p->type->type_id = SELF_DEF_TYPE;
                           (*(p->type->self_def_type)) = global_self_def_type;
                           retval = 1;                           
                       }
                       else {
                           buf_i = buf_i_start;
                           retval = 0;
                       }
                   }
                   else {
                       buf_i = buf_i_start;
                       retval = 0;
                   }
               }
               else {
                   buf_i = buf_i_start;
                   retval = 0;
               }
           }
           else {
               buf_i = buf_i_start;
               retval = 0;
           }
       }
       else {
           buf_i = buf_i_start;
           retval = 0;
       }
    }
    else {
        buf_i = buf_i_start;
        retval = 0;;
    }
    
return retval;
}


struct var_bin_tree *varrecorddefinition(struct record_type *record) {
    int buf_i_start;
    int buf_j;
    struct var_bin_tree *retval;
    char str[256];
    int local_namespace_id = namespace_id;
    
    buf_i_start = buf_i;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_var_name(str)) {
        if(create_name(str) != 0) {
            buf_i += buf_j;
            buf_j = lex_get_token_from_stream_ws(str);
            if(is_colon(str)) {
                buf_i += buf_j;
                if(is_var_type()) {
                    if((record->type = (struct type *)malloc(sizeof(struct type))) == NULL) {
                        perror("Not enough memory");
                        exit(1);
                    }
                    if(type_table[local_namespace_id].type_id == STD_SIMPLE_TYPE) {
                        record->type->type_id = STD_SIMPLE_TYPE;
                        if((record->type->std_simple_type = (struct std_simple_type *)malloc(sizeof(struct std_simple_type))) == NULL) {
                            perror("Not enough memory");
                            exit(1);
                        }
                        (*(record->type->std_simple_type)) = global_std_simple_type; 
                    }
                    else if(type_table[local_namespace_id].type_id == ENUM_TYPE) {
                        record->type->type_id = ENUM_TYPE;
                        if((record->type->enum_type = (struct enum_type *)malloc(sizeof(struct enum_type))) == NULL) {
                            perror("Not enough memory");
                            exit(1);
                        }
                        record->type->enum_type = global_enum_type;                         
                    }
                    else if(type_table[local_namespace_id].type_id == SUBRANGE_TYPE) {
                        record->type->type_id = SUBRANGE_TYPE;
                        if((record->type->subrange_type = (struct subrange_type *)malloc(sizeof(struct subrange_type))) == NULL) {
                            perror("Not enough memory");
                            exit(1);
                        }
                        (*(record->type->subrange_type)) = global_subrange_type; 
                    }
                    else if(type_table[local_namespace_id].type_id == ARRAY_TYPE) {
                        record->type->type_id = ARRAY_TYPE;
                        if((record->type->array_type = (struct array_type *)malloc(sizeof(struct array_type))) == NULL) {
                            perror("Not enough memory");
                            exit(1);
                        }
                        record->type->array_type = global_array_type; 
                        
                    }
                    else if(type_table[local_namespace_id].type_id == RECORD_TYPE) {
                        fprintf(stderr, "Hallo %i\n", local_namespace_id);
                        record->type->type_id = RECORD_TYPE;
                        if((record->type->record_type = (struct record_type *)malloc(sizeof(struct record_type))) == NULL) {
                            perror("Not enough memory");
                            exit(1);
                        }
                        record->type->record_type = pop_global_record_type_stack();
                    }
                    else if(type_table[local_namespace_id].type_id == PTR_TYPE) {
                        
                    }
                    else if(type_table[local_namespace_id].type_id == SELF_DEF_TYPE) {
                        record->type->type_id = SELF_DEF_TYPE;
                        if((record->type->self_def_type = (struct self_def_type *)malloc(sizeof(struct self_def_type))) == NULL) {
                            perror("Not enough memory");
                            exit(1);
                        }
                        (*(record->type->self_def_type)) = global_self_def_type; 
                    }
                    buf_i += buf_j;
                    if((retval = (struct var_bin_tree *)malloc(sizeof(struct var_bin_tree))) == NULL) {
                        perror("Not enough memory");
                        exit(1);
                    }
                    retval->next = NULL;
                    retval->sub = NULL;
                    retval->id = namespace_id;
                }
                else {
                    buf_i = buf_i_start;
                    retval = NULL;
                }
            }
            else {
                buf_i = buf_i_start;
                retval = NULL;
            }
        }
        else {
            buf_i = buf_i_start;
            retval = NULL;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = NULL;
    }
    
return retval;
}

struct var_bin_tree *recorddefinitioninnerpart(struct record_type *record) {
    struct var_bin_tree *root;
    
    if((root = (struct var_bin_tree *)malloc(sizeof(struct var_bin_tree *))) == NULL) {
        perror("Not enough memory");
        exit(1);
    }
    if((root = varrecorddefinition(record)) != NULL) {
        if((record->next = (struct record_type *)malloc(sizeof(struct record_type))) == NULL) {
            perror("Not enough memory");
            exit(1);
        }
        root->next = recorddefinitioninnerpart(record->next);
    }
return root;
}

struct var_bin_tree *recordtype(void) {
    int buf_i_start;
    int buf_j;
    struct var_bin_tree *retval;
    char str[256];
    struct record_type *p;

    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_record_keyword(str)) {
        type_table[namespace_id].type_id = RECORD_TYPE;
        buf_i += buf_j;
        if((p = (struct record_type *)malloc(sizeof(struct record_type))) == NULL) {
            perror("Not enough memory");
            exit(1);
        }
        push_global_record_type_stack(p);
        
        if((retval = recorddefinitioninnerpart(p)) != NULL) {
            buf_j = lex_get_token_from_stream_ws(str);
            if(is_end(str)) {
                buf_i += buf_j;
            }
            else { 
                buf_i = buf_i_start;
                retval = NULL;
            }
        }
    }
    else {
        buf_i = buf_i_start;
        retval = NULL;
    }
    
return retval;
}

int subrangetype(void) {
    int buf_i_start;
    int buf_j;
    int retval = 1;
    char str[256];
    
    buf_i_start = buf_i;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_var_name(str)) {
        strcpy(global_subrange_type.min, str);
        buf_i += buf_j;
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_two_dot(str)) {
            buf_i += buf_j;
            buf_j = lex_get_token_from_stream_ws(str);
            if(is_var_name(str)) {
                strcpy(global_subrange_type.max, str);
                buf_i += buf_j;
                retval = 1;
            }
            else {
                buf_i = buf_i_start;
                retval = 0;
            }
        }
        else {
            buf_i = buf_i_start;
            retval = 0;
        }
        
    }
    else {
        retval = 0;
        buf_i = buf_i_start;
    }
    
return retval;
}

int enum_element_chain(struct enum_type *p) {
    int buf_i_start;
    int buf_j;
    int retval = 1;
    char str[256];
    
    buf_i_start = buf_i;
        
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_var_name(str)) {
        strcpy(p->value, str);
        buf_i += buf_j;
        buf_j = lex_get_token_from_stream_ws(str);
        if (is_comma(str)) {
            buf_i += buf_j;
            if((p->next = (struct enum_type *)malloc(sizeof(struct enum_type))) == NULL) {
                perror("Not enough memory");
                exit(1);
                
            }
            retval = (retval && enum_element_chain(p->next));
        }
        else {
            p->next = NULL;
            retval = 1;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
    
return retval;
}

int selfdefinedtype(void) {
    int buf_i_start;
    int buf_j;
    int retval = 1;
    char str[256];

    buf_i_start = buf_i;    
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_var_name(str)) {
        buf_i += buf_j;
        strcpy(global_self_def_type.typename, str);
        retval = 1;
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
    
return retval;
}

int enumtype(void) {
    int buf_i_start;
    int buf_j;
    int retval = 1;
    char str[256];
    
    buf_i_start = buf_i;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_opening_round_bracket(str)) {
        buf_i += buf_j;
        if((global_enum_type = (struct enum_type *)malloc(sizeof(struct enum_type))) == NULL) {
            perror("Not enough memory");
            exit(1);
        }
        if (enum_element_chain(global_enum_type)) {
            buf_j = lex_get_token_from_stream_ws(str);
            if (is_close_round_bracket(str)) {
                buf_i += buf_j;
                retval = 1;
            }
            else {
                buf_i = buf_i_start;
                retval = 0;
            }
        }
        else {
            free(global_enum_type);
            buf_i = buf_i_start;
            retval = 0;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
    
return retval;
}

int type_string(void) {
    int buf_j;
    int buf_i_start;
    char str[128];
    int retval = 1;
    
    buf_i_start = buf_i;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_var_name(str)) {
        buf_i += buf_j;
        retval = 1;
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
return retval;
}

int vartypestring(void) {
    int buf_i_start;
    char str[128];
    int retval = 1;
    int buf_j;
    
    buf_i_start = buf_i;
    if(type_string()) {
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_semicolon(str)) {
            buf_i += buf_j;
            retval = 1;
        }
        else {
            buf_i = buf_i_start;
            retval = 0;
        }
    }
    else {
        retval = 0;
        buf_i = buf_i_start;
    }
    
return retval;
}

struct var_bin_tree *varrecordtype(void) {
    int buf_i_start;
    char str[128];
    struct var_bin_tree *retval;
    int buf_j;
    
    buf_i_start = buf_i;
    if((retval = recordtype()) != NULL) {
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_semicolon(str)) 
            buf_i += buf_j;
        else {
            buf_i = buf_i_start;
            retval = NULL;
        }
    }
    else {
        retval = NULL;
        buf_i = buf_i_start;
    }
    
return retval;
}

int varenumtype(void) {
    int buf_i_start;
    char str[128];
    int retval = 1;
    int buf_j;

    
    buf_i_start = buf_i;
    if(enumtype()) {
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_semicolon(str)) {
            buf_i += buf_j;
            retval = 1;
        }
        else {
            buf_i = buf_i_start;
            retval = 0;
        }
    }
    else {
        retval = 0;
        buf_i = buf_i_start;
    }
    
return retval;
}


int varsubrangetype(void) {
    int buf_i_start;
    char str[128];
    int retval = 1;
    int buf_j;

    
    buf_i_start = buf_i;
    if(subrangetype()) {
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_semicolon(str)) {
            buf_i += buf_j;
            retval = 1;
        }
        else {
            buf_i = buf_i_start;
            retval = 0;
        }
    }
    else {
        retval = 0;
        buf_i = buf_i_start;
    }
    
return retval;
}


int varsimpletype(void) {
    int buf_i_start;
    char str[128];
    int retval = 1;
    int buf_j;

    
    buf_i_start = buf_i;
    if(standardsimpletype()) {
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_semicolon(str)) {
            buf_i += buf_j;
            retval = 1;
        }
        else {
            buf_i = buf_i_start;
            retval = 0;
        }
    }
    else {
        retval = 0;
        buf_i = buf_i_start;
    }
    
return retval;
}

int vararraytype(void) {
    int buf_i_start;
    char str[128];
    int retval = 1;
    int buf_j;

    
    buf_i_start = buf_i;
    if(arraytype(NULL)) {
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_semicolon(str)) {
            buf_i += buf_j;
            retval = 1;
        }
        else {
            buf_i = buf_i_start;
            retval = 0;
        }
    }
    else {
        retval = 0;
        buf_i = buf_i_start;
    }
    
return retval;
}

int is_var_type(void) {
    int retval = 1;
    
    if(varsimpletype()) {
        type_table[namespace_id].type_id = STD_SIMPLE_TYPE;
        if((type_table[namespace_id].std_simple_type = (struct std_simple_type *)malloc(sizeof(struct std_simple_type))) == NULL) {
            perror("Not enough memory");
            exit(1);
        }
        *(type_table[namespace_id].std_simple_type) = global_std_simple_type; 
        retval = 1;
    }
    else if(varenumtype()) {
        type_table[namespace_id].type_id = ENUM_TYPE;
        if((type_table[namespace_id].enum_type = (struct enum_type *)malloc(sizeof(struct enum_type))) == NULL) {
            perror("Not enough memory");
            exit(1);
        }
        type_table[namespace_id].enum_type = global_enum_type;         
        retval = 1;
    }
    else if(vararraytype())  {
        type_table[namespace_id].type_id = ARRAY_TYPE;
        if((type_table[namespace_id].array_type = (struct array_type *)malloc(sizeof(struct array_type))) == NULL) {
            perror("Not enough memory");
            exit(1);
        }
        type_table[namespace_id].array_type = global_array_type;
        global_array_type = NULL;
        retval = 1;
    }
    else if(varsubrangetype()) {
        type_table[namespace_id].type_id = SUBRANGE_TYPE;
        if((type_table[namespace_id].subrange_type = (struct subrange_type *)malloc(sizeof(struct subrange_type))) == NULL) {
            perror("Not enough memory");
            exit(1);
        }
        (*type_table[namespace_id].subrange_type) = global_subrange_type;         
        retval = 1;
    }
    else if(varrecordtype() != NULL) {
        if((type_table[namespace_id].record_type = (struct record_type *)malloc(sizeof(struct record_type))) == NULL) {
            perror("Not enough memory");
            exit(1);
        }
        retval = 1;
    }
    else if(selfdefinedtype()) {
        type_table[namespace_id].type_id = SELF_DEF_TYPE;
        if((type_table[namespace_id].self_def_type = (struct self_def_type *)malloc(sizeof(struct self_def_type))) == NULL) {
            perror("Not enough memory");
            exit(1);
        }
        (*(type_table[namespace_id].self_def_type)) = global_self_def_type;
        retval = 1;
    }
    else 
        retval = 0;
    
return retval;
}

struct var_bin_tree *standardsimpletypedefinition(void) {
    int buf_i_start;
    int buf_j;
    char str[256];
    struct var_bin_tree *retval;
    
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    
    if(is_var_name(str)) {
        buf_i += buf_j;
        create_name(str);
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_equal(str)) {
            buf_i += buf_j;
            if (standardsimpletype()) {
                buf_j = lex_get_token_from_stream_ws(str);
                if (is_semicolon(str)) {
                    buf_i += buf_j;
                    if((retval = (struct var_bin_tree *)malloc(sizeof(struct var_bin_tree))) == NULL) {
                        perror ("Not enough memory\n");
                        exit(1);
                    }
                    retval->id = namespace_id;
                    retval->next = NULL;
                    retval->sub = NULL;
                }
                else {
                    buf_i = buf_i_start;
                    retval = NULL;
                }
            }
            else {
                buf_i = buf_i_start;
                retval = NULL;
            }
        }
        else {
            buf_i = buf_i_start;
            retval = NULL;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = NULL;
    }
    
return retval;
}

struct var_bin_tree *arraytypedefinition(void) {
    int buf_i_start;
    int buf_j;
    char str[256];
    struct var_bin_tree *retval;
    
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    
    if(is_var_name(str)) {
        buf_i += buf_j;
        create_name(str);
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_equal(str)) {
            buf_i += buf_j;
            if (arraytype(NULL)) {
                buf_j = lex_get_token_from_stream_ws(str);
                if (is_semicolon(str)) {
                    buf_i += buf_j;
                    if((retval = (struct var_bin_tree *)malloc(sizeof(struct var_bin_tree))) == NULL) {
                        perror ("Not enough memory\n");
                        exit(1);
                    }
                    retval->id = namespace_id;
                    retval->next = NULL;
                    retval->sub = NULL;
                }
                else {
                    buf_i = buf_i_start;
                    retval = NULL;
                }
            }
            else {
                buf_i = buf_i_start;
                retval = NULL;
            }
        }
        else {
            buf_i = buf_i_start;
            retval = NULL;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = NULL;
    }
    
return retval;
}

struct var_bin_tree *subrangetypedefinition(void) {
    int buf_i_start;
    int buf_j;
    char str[256];
    struct var_bin_tree  *retval;
    
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    
    if(is_var_name(str)) {
        buf_i += buf_j;
        create_name(str);
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_equal(str)) {
            buf_i += buf_j;
            if (subrangetype()) {
                buf_j = lex_get_token_from_stream_ws(str);
                if (is_semicolon(str)) {
                    buf_i += buf_j;
                    if((retval = (struct var_bin_tree *)malloc(sizeof(struct var_bin_tree))) == NULL) {
                        perror ("Not enough memory\n");
                        exit(1);
                    }
                    retval->id = namespace_id;
                    retval->next = NULL;
                    retval->sub = NULL;                    
                }
                else {
                    buf_i = buf_i_start;
                    retval = NULL;
                }
            }
            else {
                buf_i = buf_i_start;
                retval = NULL;
            }
        }
        else {
            buf_i = buf_i_start;
            retval = NULL;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = NULL;
    }
    
return retval;    
}

struct var_bin_tree *enumtypedefinition(void) {
    int buf_i_start;
    int buf_j;
    char str[256];
    struct var_bin_tree *retval;
    
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    
    if(is_var_name(str)) {
        buf_i += buf_j;
        create_name(str);
        buf_j = lex_get_token_from_stream_ws(str);
        if(is_equal(str)) {
            buf_i += buf_j;
            if (enumtype()) {
                buf_j = lex_get_token_from_stream_ws(str);
                if (is_semicolon(str)) {
                    buf_i += buf_j;
                    if((retval = (struct var_bin_tree *)malloc(sizeof(struct var_bin_tree))) == NULL) {
                        perror ("Not enough memory\n");
                        exit(1);
                    }
                    retval->id = namespace_id;
                    retval->next = NULL;
                    retval->sub = NULL;
                }
                else {
                    buf_i = buf_i_start;
                    retval = NULL;
                }
            }
            else {
                buf_i = buf_i_start;
                retval = NULL;
            }
        }
        else {
            buf_i = buf_i_start;
            retval = NULL;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = NULL;
    }
    
return retval;
}

struct var_bin_tree *type_definition(void) {
    int buf_i_start;
    int buf_j;
    char str[128];
    struct var_bin_tree *retval;
    
    buf_i_start = buf_i;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_type(str)) {
        buf_i += buf_j;
        if((retval = standardsimpletypedefinition()) != NULL);
        else if((retval = subrangetypedefinition()) != NULL);
        else if((retval = enumtypedefinition()) != NULL);
        else if((retval = arraytypedefinition()) != NULL);
        else {
            retval = NULL;
        }
    }
    
return retval;
}

void print_record_tree(struct record_type *p) {
    
    if (p != NULL)  {
        fprintf(stderr, "%p \n", p->type);
        print_record_tree (p->next);
    }
}

void print_type_table(void) {
    int i;
    struct enum_type *p;
    struct array_type *p2;
    struct index_type *p3;
    
    for (i = 0;  i < namespace_id;  i++) {
        printf("%i %i \n", i, type_table[i].type_id);
        printf("%s \n", type_names[type_table[i].type_id+1]);
        if(type_table[i].type_id == STD_SIMPLE_TYPE)
            printf("%s \n", type_names[type_table[i].std_simple_type->std_simple_type_id+1]);
        if(type_table[i].type_id == ENUM_TYPE) {
            for (p = type_table[i].enum_type;   p != NULL;   p = p->next)
                printf("%s ", p->value);
        }
        if(type_table[i].type_id == SUBRANGE_TYPE)
            printf("min: %s, max: %s\n", type_table[i].subrange_type->min, type_table[i].subrange_type->max);
        if(type_table[i].type_id == ARRAY_TYPE) {
            for(p2 = type_table[i].array_type;   p2 != NULL;  p2 = p2->type->array_type) {
                printf("array indizes: ");
                for (p3 = p2->index;  p3 != NULL;  p3 = p3->next_index) {
                    if(p3->index_type->type_id == STD_SIMPLE_TYPE)
                        printf("%s ", type_names[p3->index_type->std_simple_type->std_simple_type_id+1]);
                    else if(p3->index_type->type_id == ENUM_TYPE)
                        printf("Enum");
                    else if(p3->index_type->type_id == SUBRANGE_TYPE)
                        printf("Subrange");
                        
                    
                }
                
                printf("array of ");
                if (p2->type->type_id == STD_SIMPLE_TYPE) {
                    printf("array %s\n", type_names[p2->type->std_simple_type->std_simple_type_id+1]);
                    break;
                }
                else if(p2->type->type_id = SELF_DEF_TYPE) {
                    printf("array %s\n", p2->type->self_def_type->typename);
                    break;
                }
            }
        }
        if(type_table[i].type_id == RECORD_TYPE) {
            printf("Record %s %i\n", name_table[i], i);
            print_record_tree(type_table[i].record_type);
        }
        printf("<br>\n");
    }
    
}

int main(int argc, char *argv[]) {
    FILE *fp;
    char str[256];
    int i;
    
    
    int k, l;
    
    if((fp = fopen(argv[1], "r")) == NULL) {
        perror("Can't open file!");
        return -1;
    }
    get_buf(fp);
    //printf("%i\n", for_loop());
    printf("\n\n\n");
    
    init_type_table();
    
    if(program())
        printf("\n\n\nDer Code enthaelt keine Fehler - NO ERROR!!!\n");
    else
        printf("\n\n\nDer Code enthaelt einen Fehler - ERROR!!!\n");
    fclose(fp);
    
    printf("Names:\n");
    
    
    for(i = 0;  i <= namespace_id;  i++)
        printf("%s %i\n", name_table[i], i);
    
    printtree(ptr);
    print_type_table();
   // print_name_type_pointer_table();
    
}