Beispiel #1
0
int main( int argc, char * argv[] ) {
    insert_natives();

    if( argc == 1 ) {
        interactive();
        return 0;
    }

    if( argc == 2 ) {
        if( strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 ) {
            std::cout << "Usage: " << argv[0] << " [-l | -p | -s | -r] <filename>\n"
                         "\n"
                         "This program will analyse the program specified in the last argument.\n"
                         "  -l, --lexer     Do lexical analysis on the program.\n"
                         "  -p, --parser    Do syntactic analysis on the program.\n"
                         "  -s, --semantic  Do semantical analysis on the program.\n"
                         "  -r, --run       Run the program. This is the default.\n"
                         "  -h, --help      Display this help and quit.\n"
                         "If no argument is provided, run in interactive mode.\n";
            return 0;
        }
        run_program( argv[1] );
        return 0;
    }

    if( argc != 3 ) {
        std::cout << "Usage: " << argv[0] << " [-l | -p | -s | -r] <filename>\n";
        return 1;
    }

    const char * filename = argv[2];
    if( strcmp(argv[1], "-l" ) == 0 || strcmp(argv[1], "--lexer") == 0 ) {
        lexical_analysis( filename );
        return 0;
    }
    if( strcmp(argv[1], "-p" ) == 0 || strcmp(argv[1], "--parser") == 0 ) {
        syntactic_analysis( filename );
        return 0;
    }
    if( strcmp(argv[1], "-s" ) == 0 || strcmp(argv[1], "--semantic") == 0 ) {
        semantic_analysis( filename );
        return 0;
    }
    if( strcmp(argv[1], "-r" ) == 0 || strcmp(argv[1], "--run") == 0 ) {
        run_program( filename );
        return 0;
    }

    std::cerr << "Unknown option " << argv[1] << '\n';
    return 1;
}
Beispiel #2
0
/* -----------------------------------------------------------------------
 * main function, where all hell breaks loose
 * ----------------------------------------------------------------------- 
 */
int main(int argc, char **argv)
{
  parse_command_line_arguments(argc, argv, &cmdArgs);

  usrdef_init();
  symtab_init();

  /* begin parsing */
  yyparse();

  /* If there were parsing errors, exit. */
  exit_on_errors();

  /* Perform semantic analysis */
  semantic_analysis(program);

  /* If there were errors during semantic analysis, exit. */
  exit_on_errors();

  /* If we should only perform semantic analysis, exit */
  if (cmdArgs.exit_after_sem == 1) {
    exit(0);
  }

  if (cmdArgs.verbose == 1) {
    /* print the user defined data types */
    printf("USER DEFINED DATA TYPES:\n");
    printf("------------------------\n");
    usrdef_print();
    
    /* print the symbol table*/
    printf("\n\n");
    printf("SYMBOL TABLE:\n");
    printf("-------------\n");
    symtab_print(0);
  }

  /* Simple, wasn't it ?!! */

  return 0;
}
Beispiel #3
0
int main(int argc, char ** argv) {
	FILE * f;
	if (argc == 1) {
		f = fopen("../Test/test1.cmm", "r");
	}
	int i = 0;
	for (i = 1; i < argc; ++i) {
		f = fopen(argv[i], "r");
		if (!f) {
			printf("File \'%s\' not exist\n", argv[i]);
			continue;
		}
		//printf("------------------Analysis for %s------------------\n", argv[i]);
		yyrestart(f);
		lineno = 1;
		error = 0;
		current_file = argv[i];
		//:yydebug=1;
		yyparse();
		fclose(f);
		if (root && !error) {
			// print_tree(root);
			init_var_table();
			init_func_table();
			init_struct_table();
			function_field = NULL;
			//printf("now analyse\n");
			semantic_analysis(root);
			clear_var_table();
			clear_func_table();
			clear_struct_table();
		}
		putchar('\n');
	}

	return 0;
}
Beispiel #4
0
int main(int argc, char *argv[])
{
    if (argc <= 1) {
        return 1;
    }

    // ./cc src.cmm out.s
    FILE *file;
    file     = fopen(argv[1], "r");
    asm_file = fopen(argv[2], "w");

    if (!file) {
        perror(argv[1]);
        return 1;
    }
    else if (!asm_file) {
        perror(argv[2]);
        return 1;
    }

    init_strtab();

    yyrestart(file);

    yyparse();

    if (!is_syn_error) {
        semantic_analysis();

        if (!semantic_error) {
            translate();
        }
    }

    free_ast();
    return 0;
}
Beispiel #5
0
void semantic_analysis(struct tree_node * ptr) {
	if (!ptr) return;
	int i;

	if (ptr -> unit_name == NODE_EXTDEF) {
		if (ptr -> flags == FLAG_EXTDEF_VARIABLES) {
			
			struct tree_node * spec = ptr -> children[0];
			struct tree_node * declist = ptr -> children[1];
            
            push_anonymous_struct();
			// handle type first: if define struct, add struct; if basic, just use it, skip
			if (spec -> flags == FLAG_SPECIFIER_STRUCT && 
				spec -> children[0] -> flags == FLAG_STRUCTSPECIFIER_DEF) {
				symtab_add_struct(spec -> children[0]);
			}
			// whether or not spec is successfully added, just use them.
			while (declist -> flags == FLAG_EXTDECLIST_MORE) {
				symtab_add_variable(spec, declist -> children[0]);
				declist = declist -> children[2];
			}
			symtab_add_variable(spec, declist -> children[0]);
			
			pop_anonymous_struct();
			
			return;
			// end of EXTDEF_VARIABLES
		} else if (ptr -> flags == FLAG_EXTDEF_FUNCTION) {

			if (function_field != NULL) {
				semerrorpos(ERROR_OTHER, ptr->line);
				printf("nested function definition \'%s\' inside another function definition\'%s\'\n",
						ptr -> children[1] -> children[0] -> id_extra -> name,
						function_field -> name);
				return;
			}

			// register in the symbol table
			//   all the names in parameter list
			struct tree_node * spec = ptr -> children[0];
			struct tree_node * id = ptr -> children[1] -> children[0];
			struct func_entry * f = symtab_add_function(ptr -> children[1]);
			if (!f) {
				f = search_func_entry(id -> id_extra -> name);
				semerrorpos(ERROR_FUNCTION_CONFLICT, ptr -> line);
				printf("function \'%s\' already defined at %d\n",
					id -> id_extra -> name, f -> defined_at);
			}
			function_field = f;
			// check return type: if spec is a struct definition, add that.
            if (spec -> flags == FLAG_SPECIFIER_STRUCT) {
        	    struct struct_entry * se = NULL;
        	    push_anonymous_struct();
        		se = symtab_add_struct(spec -> children[0]);
        		f -> return_type_flag = TYPE_STRUCT;
        		f -> return_type.struct_type = se;
        		// return type may be NULL, checked by expression analysis
        		pop_anonymous_struct();
        	} else {
        	    assert(spec -> flags == FLAG_SPECIFIER_BASIC);
        	    f -> return_type_flag = TYPE_BASIC;
        	    f -> return_type.basic_type = spec -> children[0] -> type_name;
        	}
			// recursive analyze the definitions and statements in the compst
			struct tree_node * deflist = ptr -> children[2] -> children[1];
			while (deflist -> flags == FLAG_DEFLIST_MORE) {
				semantic_analysis(deflist -> children[0]);
				deflist = deflist -> children[1];
			}
			struct tree_node * stmtlist = ptr -> children[2] -> children[2];
			while (stmtlist -> flags == FLAG_STMTLIST_MORE) {
				semantic_analysis(stmtlist -> children[0]);
				stmtlist = stmtlist -> children[1];
			}
			function_field = NULL;
			// end of EXTDEF_FUNCTION
		} else if (ptr -> flags == FLAG_EXTDEF_TYPE) {
			if (ptr -> children[0] -> flags == FLAG_SPECIFIER_BASIC) return;
			else if (ptr -> children[0] -> flags == FLAG_SPECIFIER_STRUCT)
				symtab_add_struct(ptr -> children[0] -> children[0]);
			else assert(0);
		} else {
			assert(0);
		}
	} else if (ptr -> unit_name == NODE_EXP) {
		check_expression(ptr);
	} else if (ptr -> unit_name == NODE_DEF) {
		struct tree_node * spec = ptr -> children[0];
		struct tree_node * declist = ptr -> children[1];
		while (declist -> flags == FLAG_DECLIST_MORE) {
			symtab_add_variable(spec, declist -> children[0] -> children[0]);
			if (declist -> children[0] -> flags == FLAG_DEC_INITIALIZED) {
				check_expression(declist -> children[0] -> children[2]);
			}
			declist = declist -> children[2];
		}
		symtab_add_variable(spec, declist -> children[0] -> children[0]);
		if (declist -> children[0] -> flags == FLAG_DEC_INITIALIZED) {
			check_expression(declist -> children[0] -> children[2]);
		}
	} else if (ptr -> unit_name == NODE_STMT) {
		if (ptr -> flags == FLAG_STMT_EXP) {
			check_expression(ptr -> children[0]);
		} else if (ptr -> flags == FLAG_STMT_COMPST) {
			struct tree_node * deflist = ptr -> children[0] -> children[1];
			while (deflist -> flags == FLAG_DEFLIST_MORE) {
				semantic_analysis(deflist -> children[0]);
				deflist = deflist -> children[1];
			}
			struct tree_node * stmtlist = ptr -> children[0] -> children[2];
			while (stmtlist -> flags == FLAG_STMTLIST_MORE) {
				semantic_analysis(stmtlist -> children[0]);
				stmtlist = stmtlist -> children[1];
			}
		} else if (ptr -> flags == FLAG_STMT_IF) {
			check_expression(ptr -> children[2]);
			if (ptr -> children[2] -> exp_type_flag != TYPE_BASIC ||
				ptr -> children[2] -> exp_type.basic_type != TYPE_INT) {
				semerrorpos(ERROR_OTHER, ptr -> line);
				printf("non-integer in condition expression\n");
			}
			semantic_analysis(ptr -> children[4]);
		} else if (ptr -> flags == FLAG_STMT_IFELSE) {
			check_expression(ptr -> children[2]);
			if (ptr -> children[2] -> exp_type_flag != TYPE_BASIC ||
				ptr -> children[2] -> exp_type.basic_type != TYPE_INT) {
				semerrorpos(ERROR_OTHER, ptr -> line);
				printf("non-integer in condition expression\n");
			}
			semantic_analysis(ptr -> children[4]);
			semantic_analysis(ptr -> children[6]);
		} else if (ptr -> flags == FLAG_STMT_WHILE) {
			check_expression(ptr -> children[2]);
			if (ptr -> children[2] -> exp_type_flag != TYPE_BASIC ||
				ptr -> children[2] -> exp_type.basic_type != TYPE_INT) {
				semerrorpos(ERROR_OTHER, ptr -> line);
				printf("non-integer in condition expression\n");
			}
			semantic_analysis(ptr -> children[4]);
		} else if (ptr -> flags == FLAG_STMT_RETURN) {
			// done
			check_expression(ptr -> children[1]);
			if (function_field == NULL) {
				semerrorpos(ERROR_OTHER, ptr -> line);
				printf("no corresponding block to return operation\n");
				return;
			}
			int c = compare_type(ptr -> children[1] -> exp_type_flag, &(ptr -> children[1] -> exp_type),
				function_field -> return_type_flag, &(function_field -> return_type));
			if (c == COMPARE_GOOD) {
				// good
			} else {
				semerrorpos(ERROR_RETURN_MISMATCH, ptr -> line);
				printf("return type error: %s\n", compare_str[c]);
			}
			// end of return
		} else {
			assert(0);
		}
	} else {
		for (i = 0; i < ptr -> num_of_children; ++i) {
			assert(ptr -> children[i]);
			semantic_analysis(ptr -> children[i]);
		}
	}
	
}