📄 driver.cc
字号:
////////////////////////////////////////////////////////////////////////////////// PL/0 compiler.//// Designed by Michael Scott for CSC 252/452 at the University of// Rochester, summer 1992.//// Changed by Michal Cierniak to generate MIPS code and perform some// optimizations, fall 1993.//// Translated into C++ by Galen C. Hunt, fall 1994.//#include <string>#include <strstream>#include "inpbuf.h"#include "scanner.h"#include "parser.h"#include "symtab.h"#include "attributes.h"#include "codegen.h"#include "mips.h"#include "optimize.h"static char input_file[128] = ""; // use stdin by defaultstatic char output_file[128] = "plzero.s";// Default if source file not specified; otherwise build name from source.////////// Remind the user how the compiler is supposed to be invoked then die.//static void usage_msg(string error){ die_compiler(error + "\n\n" + "Usage:\n" + " pl0 [-C] [-g] [-spim] [-sgi] [-O[+-][pc]] [file.0]\n" + "Options:\n" + " -C : Generate comments in assembly code.\n" + " -g : Generate code with debugging symbol.\n" + " -spim : Generate spim assembly code (default).\n" + " -sgi : Generate SGI assembly code.\n" + " -O+p : Enable peephole optimization (default).\n" + " -O-p : Disable peephole optimization.\n" + " -O+c : Enable constant evaluation (default).\n" + " -O-c : Disable constant evaluation.\n");}////////// Parse command-line arguments.//static void parse_arguments(int argc, char **argv){ char * a; int i; bool toggle; string error("Invalid option: "); for (i = 1; i < argc; i++) { a = argv[i]; if (a[0] == '\0') usage_msg(error + "null string"); if (a[1] == '\0') { usage_msg(error + a); } if (a[0] == '-') { switch (a[1]) { case 'C': generate_comments = true; break; case 'g': generate_debug_code = true; break; case 's': if (a[2] == '\0'){ usage_msg(error + a); } switch (a[2]) { case 'p' : compiler_target = T_SPIM; break; case 'g' : compiler_target = T_SGI; break; default: usage_msg(error + a); break; } break; case 'O': if (a[2] == '\0' || a[3] == '\0') { usage_msg(error + a); } switch (a[2]) { case '+' : toggle = true; break; case '-' : toggle = false; break; default: usage_msg(error + a); break; } switch (a[3]) { case 'p' : g_peep_hole_optimize = toggle; break; case 'c' : evaluate_consts = toggle; break; default: usage_msg(error + a); } //case a[4] break; default: break; } } else { //must be input file name if (strlen(a) < 3) { usage_msg(error + a); } if (a[strlen(a)-2] != '.' || a[strlen(a)-1] != '0') { error = "File name does not end with `.0': "; usage_msg(error + a); } strcpy(input_file, a); strcpy(output_file, a); output_file[strlen(a)-1] = 's'; } }}////////// Takes care of all initialization that could be done when the PL/0 compiler// was compiled.//static void initialize(void){ int st_num_terminals = init_scanner(); int pt_num_terminals = init_parser(); assert(st_num_terminals == pt_num_terminals); // Scanner and parser should recognize the same number of terminals. // If you ever get this message you haven't used mungegrammar // correctly. Check for bugs in your Makefile. init_input_buffer(); init_symbol_table();}int main(int argc, char **argv){ ifstream ins; // lifetime must be all of main parse_arguments(argc, argv); if (input_file[0] != '\0') { ins.open(input_file); if (!ins) { die_compiler(string("Unable to open input file: ") + string(input_file)); } cin = ins; // read input_file as if it were standard input } initialize(); parse(); // dump_syntax_tree (ast_root); // For debugging only. if (ast_root) { ast_root->check_semantics(global_scope); // dump_syntax_tree (ast_root); // For debugging only. } if (compile_ok) { ast_root = optimize_syntax_tree(ast_root); // dump_syntax_tree (ast_root); // For debugging only. } finalize_input_buffer(); if (compile_ok) { // dump_syntax_tree (ast_root); // For debugging only. generate_code (output_file); // dump_symbol_table(); // For debugging only. } else cout << "No code generated, due to errors.\n"; return 0;}// End of File
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -