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);
}
Example #2
0
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);
}