#include <stdio.h>
#include <string.h>
#define FUNC_NAME_N_MAX 25
#define VAR_NAME_N_MAX 25
/************************* Lexer ************************/
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];
int func_name_n = 0;
int var_name_n[FUNC_NAME_N_MAX];
char func_procedure_name_table[FUNC_NAME_N_MAX][64];
char var_name_table[FUNC_NAME_N_MAX][VAR_NAME_N_MAX][64];
char func_procedure_type_table[FUNC_NAME_N_MAX][64];
char var_type_table[FUNC_NAME_N_MAX][VAR_NAME_N_MAX][64];
char var_procedure_var_table[FUNC_NAME_N_MAX][VAR_NAME_N_MAX][1];
void init_func_name_n(void) {
int i;
strcpy(func_procedure_name_table[0], "program");
strcpy(func_procedure_type_table[0], "procedure");
for(i = 0; i < FUNC_NAME_N_MAX; i++)
var_name_n[i] = 0;
return;
}
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 {
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 &= 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 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()) {
retval = 1;
buf_j = lex_get_token_from_stream_ws(str);
buf_i_start2 = buf_i;
if(is_semicolon(str)) {
buf_i += buf_j;
retval |= 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) {
retval = 1;
buf_j = lex_get_token_from_stream_ws(str);
buf_i_start2 = buf_i;
if(is_semicolon(str)) {
buf_i += buf_j;
retval |= 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) {
retval = 1;
buf_j = lex_get_token_from_stream_ws(str);
buf_i_start2 = buf_i;
if(is_comma(str)) {
buf_i += buf_j;
retval |= 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 func_name_create(char *str) {
int i;
for(i = 0; (i < func_name_n) && (i < FUNC_NAME_N_MAX); i++) {
if(strcmp(str, func_procedure_name_table[i]) == 0) {
printf("Error symbol %s already in use\n");
return 0;
}
}
if(i != FUNC_NAME_N_MAX) {
strcpy(func_procedure_name_table[i], str);
func_name_n += 1;
}
else {
printf("I'm sorry too much names in use\n");
return 0;
}
return 1;
}
int var_name_create(char *str) {
int i, j;
//j = func_name_n - 1; // Nicht - 1, weil PRPOGRAM ist auch inbegriffen - 0 !
j = func_name_n;
for(i = 0; (i < var_name_n[j]) && (i < VAR_NAME_N_MAX); i++) {
if(strcmp(str, var_name_table[j][i]) == 0) {
printf("Error symbol %s already in use\n");
return 0;
}
}
if(j != VAR_NAME_N_MAX) {
strcpy(var_name_table[j][i], str);
var_name_n[j] += 1;
}
else {
printf("I'm sorry too much names in use\n");
return 0;
}
return 1;
}
int func_type_set(char *str) {
if(func_name_n < FUNC_NAME_N_MAX) {
strcpy(func_procedure_type_table[func_name_n-1], str);
return 1;
}
return 0;
}
int var_type_set(char *str) {
if((func_name_n < FUNC_NAME_N_MAX) && ((var_name_n[func_name_n] -1) < VAR_NAME_N_MAX)){
strcpy(var_type_table[func_name_n][var_name_n[func_name_n] -1], str);
return 1;
}
return 0;
}
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(func_name_create(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;
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(func_name_create(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(void);
int functiondefinition(void) {
int buf_i_start;
int retv;
/*
*functiondefinition ::= functionheading; block;
*functionheading ::=
*
*
**/
buf_i_start = buf_i;
retv = functionheading();
if(retv == 0) {
buf_i = buf_i_start;
}
else {
if(var_definition_part()) {
retv |= 1;
}
if(functiondeclarationpart()) {
retv |= 1;
}
retv = block();
if(retv == 0)
buf_i = buf_i_start;
}
return retv;
}
int proceduredefinition(void) {
int buf_i_start;
int retv;
/*
*functiondefinition ::= functionheading; block;
*functionheading ::=
*
*
**/
buf_i_start = buf_i;
retv = procedureheading();
if(retv == 0) {
buf_i = buf_i_start;
}
else {
if(var_definition_part()) {
retv |= 1;
}
if(functiondeclarationpart()) {
retv |= 1;
}
retv = block();
if(retv == 0)
buf_i = buf_i_start;
}
return retv;
}
int functiondeclarationpart(void) {
int buf_i_start;
int retval;
buf_i_start = buf_i;
if(functiondefinition() || proceduredefinition()) {
retval = 1;
retval |= functiondeclarationpart();
}
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) {
printf("Hallo\n");
printf("%s\n", func_procedure_type_table[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(program_heading()) {
retval = 1;
if(var_definition_part()) {
retval |= 1;
}
func_name_n += 1;
if(functiondeclarationpart()) {
retval |= 1;
}
buf_j = lex_get_token_from_stream_ws(str);
if(is_begin(str)) {
buf_i += buf_j;
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 &= 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 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(var_name_create(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;
retval |= 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 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_func_name_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");
for(l = 0; l <= func_name_n; l++)
printf("%s\n", func_procedure_name_table[l]);
for(l = 0; l <= func_name_n; l++) {
printf("%s: \n", func_procedure_name_table[l]);
for(k = 0; k <= var_name_n[l]; k++)
printf("%s \n", var_name_table[l][k]);
printf("\n");
}
for(l = 0; l <= func_name_n; l++) {
printf("%s - type of return value %s\n", func_procedure_name_table[l], func_procedure_type_table[l]);
for(k = 0; k < var_name_n[l]; k++)
printf("func %s - %s - type %s\n\n", func_procedure_name_table[l], var_name_table[l][k], var_type_table[l][k]);
}
printf("---\n");
for(l = 0; l <= func_name_n; l++)
printf("%s\n", func_procedure_type_table[l]);
}