/media/sda-magnetic/david/Dok-15-2023-11-27/fernuni-hagen/cs-i-ii/old-cs-2-03/pascal-compiler/pascal-compiler-15-2020-03-25/html.txt


Also, ich habe einen riesigen Bug gefunden. Der schon vorher da war. Wenn man ein Array anlegt, dann werden da auf ein Mal jede Menge Variablen angelegt.

Nein, das ist kein derartiger Bug. Der Baum stimmt.

An dieser Stelle tauch das Problem auf, weil der Zähler (namespace_id), der auf dem Namensraum zählt - einen Sprung macht. Bei hallod auf 8, 12 und danach auf 16, 21. Da wird nicht einfach weiter gezählt. Sondern es gibt einen Sprung. Das ist nicht komplett falsch. Zumindest der Baum stimmt. Hier wird nur ein Mal hallod ausgegeben. Und bei der bisherigen Programmierung vom Baum stimmt das, da schauen wir so oder so nur im Baum in der Tabelle nach, welchen Namen der hat. Und da der Index stimmt, der im Baum ist, funktioniert das so.

Das ist so zu sagen einfach ein verweistes Objekt - ein ungültiges Objekt - sagt man da.

#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

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 self_def_type {
    struct type *type;
};

struct std_simple_type {
    int std_simple_type_id;
};

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

struct subrange_type {
    
};

struct array_type {
    
};

struct record_type {
    
};

struct ptr_type {
    
};

struct std_simple_type global_std_simple_type;
struct enum_type *global_enum_type;

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












int enum_element_chain(struct enum_type *p) {
    int buf_i_start;
    int buf_j;
    int retval;
    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 enumtype(void) {
    int buf_i_start;
    int buf_j;
    int retval;
    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 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;
}







void print_type_table(void) {
    int i;
    struct enum_type *p;
    
    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);
        printf("<br>\n");
    }
    
}







#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

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 self_def_type {
    struct type *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 array_type {
    
};

struct record_type {
    
};

struct ptr_type {
    
};

struct self_defined_type {
    struct type *type;
};

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;

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












int subrangetype(void) {
    int buf_i_start;
    int buf_j;
    int retval;
    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 is_var_type(void) {
    int retval;
    
    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()) 
        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(vartypestring())
        retval = 1;
    else if(varrecordtype() != NULL)
        retval = 1;
    else 
        retval = 0;
    
return retval;
}











int is_var_type(void) {
    int retval;
    
    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()) 
        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(vartypestring())
        retval = 1;
    else if(varrecordtype() != NULL)
        retval = 1;
    else 
        retval = 0;
    
return retval;
}







#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

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

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

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(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_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;
    }
    
return retval;
}

struct var_bin_tree *recorddefinitioninnerpart(void) {
    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()) != NULL)
        root->next = recorddefinitioninnerpart();
return root;
}

struct var_bin_tree *recordtype(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_record_keyword(str)) {
        buf_i += buf_j;
        if((retval = recorddefinitioninnerpart()) != 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 {
        perror("Hallo");
        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)
        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_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;
                }
            }
        }
        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();
    
}