/media/sda-magnetic/david/Extern-Magnetic-2022-06-29/Extern01/Dokumente-2021-05-8/disk10-ab-2020-01-10/02-debian-pc2-work/informatik/pascal-compiler/2020-01-22-types-and-tree/pascal90.c


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

#define NAME_N_MAX 128

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

struct namespacebintree {
    struct namespacebintree *left;
    struct namespacebintree *right;
    int id;
};

#define NAMESPACE_INHERITANCE   1
#define NAMESPACE_NEXT          0
int namespace_id = 0;

struct namespacebintree *root;
char name_table[NAME_N_MAX][64];

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


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;
    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;
    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 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) {
        buf_i += buf_j;
        retval = 1;
    }
    else if(strcmp(str, "real") == 0) {
        buf_i += buf_j;
        retval = 1;
    }
    else if(strcmp(str, "boolean") == 0) {
        buf_i += buf_j;
        retval = 1;
    }
    else if(strcmp(str, "char") == 0) {
        buf_i += buf_j;
        retval = 1;
    }
    else if(strcmp(str, "string") == 0) {
        buf_i += buf_j;
        retval = 1;
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
return retval;
}

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)) {
        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)) {
                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(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)) {
        buf_i += buf_j;
        buf_j = lex_get_token_from_stream_ws(str);
        if (is_comma(str)) {
            buf_i += buf_j;
            retval = (retval && enum_element_chain());
        }
        else {
            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 (enum_element_chain()) {
            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 {
            buf_i = buf_i_start;
            retval = 0;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
    
return retval;
}

int standardsimpletypedefinition(void) {
    int buf_i_start;
    int buf_j;
    char str[256];
    int retval;
    
    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_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;
                    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 subrangetypedefinition(void) {
    int buf_i_start;
    int buf_j;
    char str[256];
    int retval;
    
    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_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;
                    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 enumtypedefinition(void) {
    int buf_i_start;
    int buf_j;
    char str[256];
    int retval;
    
    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_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;
                    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 type_definition(void) {
    int retval = 0;
    int buf_i_start;
    
    buf_i_start = buf_i;
    
    
    if(standardsimpletypedefinition()) 
        retval = 1;
    else if(subrangetypedefinition()) 
        retval = 1;
    else if(enumtypedefinition())
        retval = 1;
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
    
return retval;
}

int type_declaration_part(void) {
    int buf_i_start;
    char str[256];
    int retval;
    
    buf_i_start = buf_i;
    if(type_definition()) {
        retval = 1;
        type_declaration_part();
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
return retval;
}

int typedeclarationpart(void) {
    int buf_i_start;
    int buf_j;
    char str[256];
    int retval;
    
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_type(str)) {
        buf_i += buf_j;
        if(type_declaration_part()){retval = 1;}
        else {
            buf_i = buf_i_start;
            retval = 0;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
    
return retval;
}

int programparameter(void) {
    char str[256];
    int buf_i_start;
    int buf_j;
    int retval;
    /*
     * 
     * <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;
    /*
     * 
     * <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;
    /*
     * 
     * <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;
    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;
    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;
    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;
    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;
    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;
    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;
    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 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;    
    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 func_type_set(char *str) {
    return 1;
}
    
int procedureheading(void) {
    char str[256];
    int buf_i_start;
    int retval;    
    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 block(void) {
    char str[256];
    int retval;
    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 var_definition_part(void);
int functiondeclarationpart(struct namespacebintree *root, int inheritanceflag);
    
int functiondefinition(struct namespacebintree *root, int inheritanceflag) {
    int buf_i_start;
    int retv;
    struct namespacebintree *tmp;
    
    /*
  *functiondefinition ::= functionheading; block;
  *functionheading ::= 
  *
  *
  **/   
    
    buf_i_start = buf_i;
    retv = functionheading();
    if(retv == 0) {
        buf_i = buf_i_start; 
    }
    else {
        if(type_declaration_part()) {
            retv = 1;
        }
        if(var_definition_part()) {
            retv = 1;
        }
        if(functiondeclarationpart(root, NAMESPACE_INHERITANCE)) {
            retv = 1;
        }
        retv = block();
        if(retv == 0)
            buf_i = buf_i_start;
        else {
            if((tmp = (struct namespacebintree *)malloc(sizeof(struct namespacebintree))) == NULL) {
                perror ("Not enough memory");
                exit(1);
            }
            if(inheritanceflag) {
                tmp->id = namespace_id;
                tmp->left = root->left;
                root->left = tmp;
                tmp->right = NULL;
            }
            else {
                tmp->id = namespace_id+1;
                tmp->right = root->right;
                root->right = tmp;
                tmp->left = NULL;
            }
        }

    }
    
return retv;
}

int proceduredefinition(struct namespacebintree *root, int inheritanceflag) {
    int buf_i_start;
    int retv;
    struct namespacebintree *tmp;
    
    /*
  *functiondefinition ::= functionheading; block;
  *functionheading ::= 
  *
  *
  **/   
    
    buf_i_start = buf_i;
    
    retv = procedureheading();
    if(retv == 0) {
        buf_i = buf_i_start; 
    }
    else {
        if(type_declaration_part()) {
            retv = 1;
        }
        if(var_definition_part()) {
            retv = 1;
        }
        if(functiondeclarationpart(root, NAMESPACE_INHERITANCE)) {
            retv = 1;
        }

        retv = block();
        if(retv == 0)
            buf_i = buf_i_start;
        else {
            if((tmp = (struct namespacebintree *)malloc(sizeof(struct namespacebintree))) == NULL) {
                perror ("Not enough memory");
                exit(1);
            }
            if(inheritanceflag) {
                tmp->id = namespace_id;
                tmp->left = root->left;
                root->left = tmp;
                tmp->right = NULL;
            }
            else {
                tmp->id = namespace_id;
                tmp->right = root->right;
                root->right = tmp;
                tmp->left = NULL;
            }
        }
    }
    
return retv;
}


int functiondeclarationpart(struct namespacebintree *root, int inheritanceflag) {
    int buf_i_start;
    int retval;
    int r1, r2;
    
    buf_i_start = buf_i;
    
    r1 = functiondefinition(root, inheritanceflag);
    r2 = proceduredefinition(root, inheritanceflag);
    
    if(r1 || r2) {
        retval = 1;
        functiondeclarationpart(root, NAMESPACE_NEXT);
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
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;
    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;
}

int var_definition_part(void);

int program(void) {
    int retval;
    int buf_i_start;
    char str[256];
    int buf_j;
    
    buf_i_start = buf_i;
    
    if((root = (struct namespacebintree *)malloc(sizeof(struct namespacebintree))) == NULL) {
        perror("Not enough memory\n");
        exit(1);
    }
    root->id = 0;
    
    if(program_heading()) {
        retval = 1;     
        if(typedeclarationpart()) {
            retval = 1;
        }
        if(var_definition_part()) {
            retval = 1;
        }
        
        if(functiondeclarationpart(root, NAMESPACE_INHERITANCE)) {
            retval = 1;
        }
        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;
}

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

int vardefinition(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)) {
        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;
                buf_j = lex_get_token_from_stream_ws(str);
                if(is_var_name(str)) {
                    if(var_type_set(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;
                        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;
}

int vardefinitionpart(void) {
    int buf_i_start;
    int retval;
    
    buf_i_start = buf_i;
    if(vardefinition()) {
        retval = 1;
        vardefinitionpart();
    }
    else {
        retval = 0;
        buf_i = buf_i_start;
    }
return retval;
}

int var_definition_part(void) {
    char str[256];
    int buf_j;
    int buf_i_start;
    int retval;
    
    buf_i_start = buf_i;
    
    buf_j = lex_get_token_from_stream_ws(str);
    if(is_var_procedure_attribute(str)) {
        buf_i += buf_j;
        if(vardefinitionpart()) {
            retval = 1;
        }
        else {
            retval = 0;
            buf_i = buf_i_start;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
return retval;
}

int printtree(struct namespacebintree *root) {
    if(root != NULL) {
    

            printtree(root->right);
            printf("%s %i, ", name_table[root->id], root->id);
/*            if(root->right != NULL)
                printf("l: %s %i ", name_table[root->right->id], root->right->id);
            else 
                printf("l: null ");
            if(root->left != NULL)
                printf("r: %s %i ", name_table[root->left->id], root->left->id);
            else 
                printf("r: null ");*
            printf("\n\n");*/
            printtree(root->left);
        
        
    }
}

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


        printtree(root);
        
        for(i = 0;  i <= namespace_id;  i++)
            printf("%s %i\n", name_table[i], i);
    
}