void coding(std::vector<std::string> code, std::string file) { char filename[] = "c://files//test.txt"; // 此处写入文件名; std::ofstream yout(filename, ios::out); std::string abundant_code,shell_code,final_code; int n = 0; for (int i = 0; i < 128; i++) { if (counting[i] != 0) n = n + 1; } yout << n; for (int i = 0; i < 128; i++) { if (counting[i] != 0) yout << " " << (char)i << " " << code[i]; } yout << " "; yout << file.size(); yout << " "; for (int i=0; i<file.size();i++) { if (abundant_code.size()!=0) { shell_code=shell_code+abundant_code; abundant_code=""; } shell_code=shell_code+code[(int)file[i]]; if (shell_code.size()>=8) { string abuntdant_code(shell_code,8,8); abundant_code = abuntdant_code; string final_code(shell_code,0,8); yout << output(final_code); shell_code=""; } } int size = shell_code.size(); if (size != 0) for (int i = 0; i < 8 - size; i++) shell_code = shell_code + "0"; yout<<output(shell_code); }
void parse_program(char *filename) { printf("parsing file: %s\n", filename); yyfiles = list_new(NULL, &free); log_assert(yyfiles); list_push_back(yyfiles, filename); yyclibs = list_new(NULL, &free); log_assert(yyclibs); yyincludes = hasht_new(8, true, NULL, NULL, NULL); log_assert(yyincludes); /* open file for lexer */ yyin = fopen(filename, "r"); if (yyin == NULL) log_error("could not open input file: %s", filename); /* push buffer state for lexer */ yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE)); /* setup yytypes table for lexer */ yytypes = hasht_new(8, true, NULL, NULL, &free_typename); log_assert(yytypes); /* reset library flags */ libs.usingstd = false; libs.cstdlib = false; libs.cmath = false; libs.ctime = false; libs.cstring = false; libs.fstream = false; libs.iostream = false; libs.string = false; libs.iomanip = false; log_debug("invoking Bison"); int result = yyparse(); if (result != 0) exit(2); /* print syntax tree */ if (arguments.tree) tree_traverse(yyprogram, 0, &print_tree, NULL, NULL); /* initialize scope stack */ log_debug("setting up for semantic analysis"); yyscopes = list_new(NULL, NULL); log_assert(yyscopes); struct hasht *global = hasht_new(32, true, NULL, NULL, &symbol_free); log_assert(global); list_push_back(yyscopes, global); /* build the symbol tables */ log_debug("populating symbol tables"); region = GLOBE_R; offset = 0; symbol_populate(yyprogram); log_debug("global scope had %zu symbols", hasht_used(global)); /* constant symbol table put in front of stack for known location */ struct hasht *constant = hasht_new(32, true, NULL, NULL, &symbol_free); log_assert(constant); list_push_front(yyscopes, constant); region = CONST_R; offset = 0; log_debug("type checking"); type_check(yyprogram); /* generating intermediate code */ log_debug("generating intermediate code"); yylabels = 0; /* reset label counter */ code_generate(yyprogram); struct list *code = ((struct node *)yyprogram->data)->code; /* iterate to get correct size of constant region */ size_t string_size = 0; for (size_t i = 0; i < constant->size; ++i) { struct hasht_node *slot = constant->table[i]; if (slot && !hasht_node_deleted(slot)) { struct typeinfo *v = slot->value; if (v->base == FLOAT_T) string_size += 8; else if (v->base == CHAR_T && v->pointer) string_size += v->token->ssize; } } /* print intermediate code file if debugging */ if (arguments.debug) { char *output_file; asprintf(&output_file, "%s.ic", filename); FILE *ic = fopen(output_file, "w"); if (ic == NULL) log_error("could not save to output file: %s", output_file); fprintf(ic, ".file \"%s\"\n", filename); /* print .string region */ fprintf(ic, ".string %zu\n", string_size); /* iterate to print everything but ints, chars, and bools */ for (size_t i = 0; i < constant->size; ++i) { struct hasht_node *slot = constant->table[i]; if (slot && !hasht_node_deleted(slot)) { struct typeinfo *v = slot->value; if (v->base == FLOAT_T || (v->base == CHAR_T && v->pointer)) { fprintf(ic, " "); print_typeinfo(ic, slot->key, v); fprintf(ic, "\n"); } } } /* print .data region */ fprintf(ic, ".data\n"); for (size_t i = 0; i < global->size; ++i) { struct hasht_node *slot = global->table[i]; if (slot && !hasht_node_deleted(slot)) { struct typeinfo *value = slot->value; if (value->base != FUNCTION_T) { fprintf(ic, " "); print_typeinfo(ic, slot->key, value); fprintf(ic, "\n"); } } } fprintf(ic, ".code\n"); print_code(ic, code); fclose(ic); free(output_file); } log_debug("generating final code"); /* copy because Wormulon */ char *copy = strdup(filename); char *base = basename(copy); free(copy); char *output_file; asprintf(&output_file, "%s.c", base); FILE *fc = fopen(output_file, "w"); if (fc == NULL) log_error("could not save to output file: %s", output_file); time_t t = time(NULL); struct tm *local = localtime(&t); char timestamp[60]; strftime(timestamp, sizeof(timestamp), "%F %T", local); fprintf(fc, "/*\n"); fprintf(fc, " * %s - 120++ Three-Address C Code\n", output_file); fprintf(fc, " * Generated @ %s\n", timestamp); fprintf(fc, " *\n"); fprintf(fc, " * Created by Andrew Schwartzmeyer's 120++ Compiler\n"); fprintf(fc, " * Project located @ https://github.com/andschwa/uidaho-cs445\n"); fprintf(fc, " */\n\n"); fprintf(fc, "/* Required includes for TAC-C */\n"); fprintf(fc, "#include <stdlib.h>\n"); fprintf(fc, "#include <stdbool.h>\n"); fprintf(fc, "#include <string.h>\n"); if (libs.usingstd && libs.iostream) fprintf(fc, "#include <stdio.h>\n"); fprintf(fc, "\n"); /* include passed-through C headers */ fprintf(fc, "/* Source-file C headers */\n"); struct list_node *iter = list_head(yyclibs); while (!list_end(iter)) { fprintf(fc, "#include %s\n", (char *)iter->data); iter = iter->next; } fprintf(fc, "\n"); /* get maximum param size for faux stack */ size_t max_param_size = 0; iter = list_head(code); while (!list_end(iter)) { struct op *op = iter->data; if (op->code == PROC_O) { size_t param_size = op->address[0].offset; if (param_size > max_param_size) max_param_size = param_size; } iter = iter->next; } fprintf(fc, "/* Memory regions */\n"); fprintf(fc, "char constant[%zu];\n", string_size); fprintf(fc, "char global[%zu];\n", global->size); fprintf(fc, "char stack[%zu];\n", max_param_size); fprintf(fc, "\n"); fprintf(fc, "/* Final Three-Address C Generated Code */\n"); final_code(fc, code); fclose(fc); /* remove TAC-C "assembler" code */ if (!arguments.assemble) { /* compile object files */ char *command; asprintf(&command, "gcc -c %s", output_file); int status = system(command); if (status != 0) log_error("command failed: %s", command); remove(output_file); } free(output_file); /* clean up */ log_debug("cleaning up"); tree_free(yyprogram); yylex_destroy(); hasht_free(yytypes); free(yyincludes); /* values all referenced elsewhere */ list_free(yyfiles); list_free(yyclibs); list_free(yyscopes); }