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; }
/* ----------------------------------------------------------------------- * 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; }
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; }
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; }
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]); } } }