/media/sda-magnetic/david/Extern-Magnetic-2022-06-29/Extern01/Dokumente-2020-11-16/disk10-ab-2020-01-10/02-debian-pc2-work/informatik/pascal-compiler/siac4tread-first/tcpiplang21.c


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

int is_while(char *);
int is_if(char *);
int is_fi(char *);
int is_then(char *);
int is_else(char *);
int is_do(char *);
int is_od(char *);
int is_begin(char *);
int is_end(char *);
int is_set(char *);
int is_id(char *);
int is_plus(char *);
int is_mult(char *);
int is_minus(char *);
int is_div(char *);
int is_semicolon(char *);
int is_open_round_bracked(char *);
int is_closed_round_bracked(char *);
int is_cop_equal(char *);
int is_cop_less(char *);
int is_cop_greater(char *);
int is_cop_less_equal(char *);
int is_cop_greater_equal(char *);
int is_num(char *);

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 is_if(char *str) {return ((str[0] == 'i') && (str[1] == 'f') && (str[2] == 0));}
int is_fi(char *str) {return ((str[0] == 'f') && (str[1] == 'i') && (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'));}
int is_do(char *str) {return ((str[0] == 'd') && (str[1] == 'o') && (str[2] == 0));}
int is_od(char *str) {return ((str[0] == 'o') && (str[1] == 'd') && (str[2] == 0));}
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_print(char *str) {return ((str[0] == 'p') && (str[1] == 'r') && (str[2] == 'i') && (str[3] == 'n') && (str[4] == 't') && (str[5] == 0));} 
int is_end(char *str) {return ((str[0] == 'e') && (str[1] == 'n') && (str[2] == 'd') && (str[3] == 0));}
int is_set(char *str) {return ((str[0] == ':') && (str[1] == '=') && (str[2] == 0));}
int is_id(char *str) {return ((str[0] >= 'a') && (str[0] <= 'z') && (str[1] == 0));}
int is_plus(char *str) {return ((str[0] == '+') && (str[1] == 0));}
int is_minus(char *str) {return ((str[0] == '-') && (str[1] == 0));}
int is_mult(char *str) {return ((str[0] == '*') && (str[1] == 0));}
int is_div(char *str) {return ((str[0] == '/') && (str[1] == 0));}
int is_semicolon(char *str) {return ((str[0] == ';') && (str[1] == 0));}
int is_open_round_bracked(char *str) {return ((str[0] == '(') && (str[1] == 0));}
int is_closed_round_bracked(char *str) {return ((str[0] == ')') && (str[1] == 0));}
int is_cop_equal(char *str) {return ((str[0] == '=') && (str[1] == '=') && (str[2] == 0));}
int is_cop_less(char *str) {return ((str[0] == '<') && (str[1] == 0));}
int is_cop_less_equal(char *str) {return ((str[0] == '<') && (str[1] == '=') && (str[2] == 0));}
int is_cop_greater(char *str) {return ((str[0] == '>') && (str[1] == 0));}
int is_cop_greater_equal(char *str) {return ((str[0] == '>') && (str[1] == '=') && (str[2] == 0));}
int is_num(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;
}


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

char var_name_str_array[128][128];
int var_name_str_array_stack_ptr = 0;

void push_var_name_str(char *str) {
    strcpy(var_name_str_array[var_name_str_array_stack_ptr], str);
    var_name_str_array_stack_ptr++;
return;
}

void pop_var_name_str(char *str) {
    var_name_str_array_stack_ptr--;
    strcpy(str, var_name_str_array[var_name_str_array_stack_ptr]);
return;
}

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


char label_str_array[128][128];
int label_str_array_stack_ptr = 0;

void push_label_str(char *str) {
    strcpy(label_str_array[label_str_array_stack_ptr], str);
    label_str_array_stack_ptr++;
return;
}

void pop_label_str(char *str) {
    label_str_array_stack_ptr--;
    strcpy(str, label_str_array[label_str_array_stack_ptr]);
return;
}

int expr_next_label_i = 1;

void get_prev_label(char *str) {
    sprintf(str, "label %i", expr_next_label_i-1);
return;
}

void get_next_label(char *str) {
    sprintf(str, "label %i", expr_next_label_i);
    expr_next_label_i++;
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;
}

int statement(void);
int statement2(void);
int assignment(void);
int cond(void);
int loop(void);
int expr(void);
int boolexpr(void);
int numexpr(void);
int numexpr2(void);
int term(void);
int term2(void);
int factor (void);
int print (void);
int program (void);
int id (void);

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

    if(assignment()) 
        retval = 1;
    else if(cond()) 
        retval = 1;
    else if(loop())
        retval = 1;
    else if(print())
        retval = 1;
    else {
        buf_i = buf_i_start;
        retval = 0;
    }

return retval;
}

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

return retval;
}

int id (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_id(str)) {
        buf_i += buf_j;
        retval = 1;
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }

return retval;
}


int print (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_print(str)) {
        printf("print ");
        buf_i += buf_j;
        buf_j = lex_get_token_from_stream_ws(str);
        if (is_id(str)) { 
            printf("%s\n", str);
            buf_i += buf_j;
            retval = 1;
        }
        else {
            buf_i = buf_i_start;
            retval = 0;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }

return retval;
}

int assignment(void) {
    char str[256];
    char str1[256];
    char str2[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_id(str)) {
        push_var_name_str(str);
        buf_i += buf_j;
        buf_j = lex_get_token_from_stream_ws(str);
        if (is_set(str)) {
            buf_i += buf_j;
            if (numexpr()) {
                pop_var_name_str(str1);
                pop_var_name_str(str2);
                printf("set %s, %s\n", str2, str1);
                return 1;
            }
            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 cond(void) {
    char str[256];
    char label_str[256];
    char label_str2[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_if(str)) {
        buf_i += buf_j;
        
        printf("jump if not\n");
        if (boolexpr()) {
            get_next_label(label_str);
            push_label_str(label_str);
            printf("to %s\n", label_str);
            buf_j = lex_get_token_from_stream_ws(str);
            if (is_then(str)) {
                buf_i += buf_j;
                if (statement()) {
                    buf_j = lex_get_token_from_stream_ws(str);
                    if (is_fi(str)) {
                        buf_i += buf_j;
                        retval = 1;
                        pop_label_str(label_str);
                        printf("%s \n", label_str);
                    }
                    else if (is_else(str)) {
                        get_next_label(label_str2);
                        printf("jmp to %s\n", label_str2);
                        pop_label_str(label_str);
                        push_label_str(label_str2);
                        printf("%s \n", label_str);
                        buf_i += buf_j;
                        if (statement()) {
                            buf_j = lex_get_token_from_stream_ws(str);
                            if (is_fi(str)) {
                                buf_i += buf_j;
                                retval = 1;
                            }
                            else {
                                buf_i = buf_i_start;
                                retval = 0;
                            }
                        }
                        else {
                            buf_i = buf_i_start;
                            retval = 0;
                        }
                        pop_label_str(label_str);
                        printf("%s \n", label_str);
                    }
                    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 {
        retval = 0;
        buf_i = buf_i_start;
    }
    
return retval;
}


int loop(void) {
    char str[256];
    int buf_i_start;
    int retval = 1;
    int buf_j;
    char label_str[128];
    char label_str2[128];
    
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    
    if (is_while(str)) {
        buf_i += buf_j;
        get_next_label(label_str2);
        printf("%s\n", label_str2);
        push_label_str(label_str2);
        printf("jump if not\n");
        if (boolexpr()) {
            get_next_label(label_str);
            push_label_str(label_str);
            printf("to %s\n", label_str);
            buf_j = lex_get_token_from_stream_ws(str);
            if (is_do(str)) {
                buf_i += buf_j;
                if(statement()) {
                    buf_j = lex_get_token_from_stream_ws(str);
                    if (is_od(str)) {
                        buf_i += buf_j;
                        retval = 1;
                        pop_label_str(label_str);
                        pop_label_str(label_str2);
                        printf("jump to %s\n", label_str2);
                        printf("%s \n", label_str);
                    }
                    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 expr(void) {
    int buf_i_start;
    int retval = 1;
    
    buf_i_start = buf_i;
    
    if (boolexpr())
        retval = 1;
    else if (numexpr())
        retval = 1;
    else {
        buf_i = buf_i_start;
        retval = 0;
    }
    
return retval;
}

int boolexpr(void) {
    char str[256];
    int buf_i_start;
    int retval = 1;
    int buf_j;
    char tmp_str2[128];
    char tmp_str3[128];
    
    buf_i_start = buf_i;
    
    if (numexpr()) {
        buf_j = lex_get_token_from_stream_ws(str);
        if (is_cop_equal(str)) {
            buf_i += buf_j;
            if (numexpr()) {
                pop_var_name_str(tmp_str2);
                pop_var_name_str(tmp_str3);
                printf("equal %s, %s\n", tmp_str2, tmp_str3);
                retval = 1;
            }
            else {
                buf_i = buf_i_start;
                retval = 0;
            }
        }
        else if (is_cop_greater(str)) {
            buf_i += buf_j;
            if (numexpr()) {
                pop_var_name_str(tmp_str2);
                pop_var_name_str(tmp_str3);
                printf("greater %s, %s\n", tmp_str2, tmp_str3);
                retval = 1;
            }
            else {
                buf_i = buf_i_start;
                retval = 0;
            }
        }
        else if (is_cop_greater_equal(str)) {
            buf_i += buf_j;
            if (numexpr()) {
                pop_var_name_str(tmp_str2);
                pop_var_name_str(tmp_str3);
                printf("greaterequal %s, %s\n", tmp_str2, tmp_str3);
                retval = 1;
            }
            else {
                buf_i = buf_i_start;
                retval = 0;
            }            
        }
        else if (is_cop_less(str)) {
            buf_i += buf_j;
            if (numexpr()) {
                pop_var_name_str(tmp_str2);
                pop_var_name_str(tmp_str3);
                printf("less %s, %s\n", tmp_str2, tmp_str3);
                retval = 1;
            }
            else {
                buf_i = buf_i_start;
                retval = 0;
            }
        }
        else if (is_cop_less_equal(str)) {
            buf_i += buf_j;
            if (numexpr()) {
                pop_var_name_str(tmp_str2);
                pop_var_name_str(tmp_str3);
                printf("lessequal %s, %s\n", tmp_str2, tmp_str3);
                retval = 1;
            }
            else {
                buf_i = buf_i_start;
                retval = 0;
            }
        }
        else {
            retval = 0;
            buf_i = buf_i_start;
        }
    }
    else {
        retval = 0;
        buf_i = buf_i_start;
    }
    
return retval;
}


int numexpr(void) {
    char str[256];
    int buf_i_start;
    int retval = 1;
    int retval2;
    int retval3;
    int buf_j;
    
    buf_i_start = buf_i;
    
    retval2 = term();
    if (retval2) {
        retval3 = numexpr2 ();
        if(retval3);
        else {
            buf_i = buf_i_start;
            retval = 0;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }

return (retval | retval2 | retval3);
}

int numexpr2(void) {
    char str[256];
    int buf_i_start;
    int retval = 1;
    int retval2;
    int retval3;
    int buf_j;
    char tmp_str[128];
    char tmp_str2[128];
    char tmp_str3[128];
    char tmp_str4[128];

    
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_plus(str)) {
        buf_i += buf_j;
        retval2 = term ();
        pop_var_name_str(tmp_str2);
        pop_var_name_str(tmp_str3);
        expr_get_next_var_name(tmp_str4);
        printf("add %s, %s, %s\n", tmp_str4, tmp_str2, tmp_str3);
        push_var_name_str(tmp_str4);
        if(retval2) {
           retval3 = numexpr2 ();
           if(retval3);
           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 | retval2 | retval3);
}


int term(void) {
    char str[256];
    int buf_i_start;
    int retval = 1;
    int buf_j;
    int retval2;
    int retval3;
    
    buf_i_start = buf_i;
    
    retval2 = factor();
    if (retval2) {
        retval3 = term2 ();
        if(retval3);
        else {
            buf_i = buf_i_start;
            retval = 0;
        }
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }

return (retval | retval2 | retval3);
}

int term2(void) {
    char str[256];
    int buf_i_start;
    int retval = 1;
    int retval2;
    int retval3;
    int buf_j;
    char tmp_str[128];
    char tmp_str2[128];
    char tmp_str3[128];
    char tmp_str4[128];

    
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_mult(str)) {
        buf_i += buf_j;
        retval2 = factor ();
        pop_var_name_str(tmp_str2);
        pop_var_name_str(tmp_str3);
        expr_get_next_var_name(tmp_str4);
        printf("mul %s, %s, %s\n", tmp_str4, tmp_str2, tmp_str3);
        push_var_name_str(tmp_str4);
        
        if(retval2) {
           retval3 = term2 ();
           if(retval3);
           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 | retval2 | retval3);
}


int factor (void) {
    char str[256];
    int buf_i_start;
    int retval = 1;
    int buf_j;
    char tmp_str[128];
    char tmp_str2[128];
    char tmp_str3[128];
    char tmp_str4[128];
    
    buf_i_start = buf_i;
    buf_j = lex_get_token_from_stream_ws(str);
    if (is_id(str)) {
        buf_i += buf_j;
        retval = 1;
        push_var_name_str(str);
    }
    else if (is_open_round_bracked(str)) {
        buf_i += buf_j;
        if (retval = numexpr()) {
            buf_j = lex_get_token_from_stream_ws(str);
            if (is_closed_round_bracked(str)) {
                buf_i += buf_j;
                retval = 1;
            }
        }
        else {
            buf_i = buf_i_start;
            retval = 0;
        }
    }
    else if (is_num(str)) {
        buf_i += buf_j;
        retval = 1;
        push_var_name_str(str);
    }
    else {
        buf_i = buf_i_start;
        retval = 0;
    }

return retval;
}

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

return retval;
}

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

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

int main(int argc, char *argv[]) {
    FILE *fp;
    char str[256];
    
    if((fp = fopen(argv[1], "r")) == NULL) {
        perror("Can't open file!");
        return -1;
    }
    get_buf(fp);

    
    if(program())
        fprintf(stderr, "\n\n\nDer Code enthaelt keine Fehler - NO ERROR!!!\n");
    else
        fprintf(stderr, "\n\n\nDer Code enthaelt einen Fehler - ERROR!!!\n");
    fclose(fp);
    
return 0;    
}