public static void main(String[] args) throws FileNotFoundException,
			UnsupportedEncodingException {
		Options opt = new Options();
		CmdLineParser cmdParser = new CmdLineParser(opt);
		cmdParser.setUsageWidth(80);
		try {
			cmdParser.parseArgument(args);
			if (opt.arguments.size() == 0) {
				System.err.println("we need at lease one input file");
				cmdParser.printUsage(System.err);
				return;
			}
		} catch (CmdLineException e) {
			System.err.println(e.getMessage());
			cmdParser.printUsage(System.err);
			return;
		}

		String path = opt.arguments.get(0);
		Optimizer.LEVEL level = Optimizer.LEVEL.values()[opt.optimizeLevel];

		Parser parser;
		try {
			parser = new Parser(path);
			parser.parse();
		} catch (IOException e) {
			System.err.println("File not found:" + path);
			return;
		} catch (SyntaxFormatException e) {
			System.err.println("Syntax error:" + e.getMessage());
			return;
		} catch (Exception e) {
			System.err.println("Sementic error:" + e.getMessage());
			return;
		}

		Block mainBlock = parser.getRootBlock();

		printInitGraph(mainBlock, path);

		Optimizer optimizer = new Optimizer(level);
		optimizer.optimize(parser.getRootBlock());
		for (Function func : Function.getAllFunction()) {
			optimizer.optimize(func.getBody().getFirstBlock());
		}

		printOptimizedGraph(mainBlock, path);

		RegisterAllocator allocator = new RegisterAllocator(opt.regNum);

		printInterferenceGraph(allocator, mainBlock, path);

		CodeGenerator mainGen = new CodeGenerator("main", mainBlock, allocator);

		ArrayList<CodeGenerator> generators = new ArrayList<CodeGenerator>();
		for (Function func : Function.getAllFunction()) {
			generators.add(new CodeGenerator(func.getName(), func.getBody().getFirstBlock(),
					allocator));
		}
		Linker linker = new Linker(mainGen, generators);

		Integer[] codes = linker.linkThem();
		printCode(path, codes);

		printFinalGraph(mainBlock, path);

		if (opt.runDLX) {
			DLX.load(codes);
			try {
				DLX.execute(false);
			} catch (IOException e) {
				e.printStackTrace();
				return;
			}
		}
	}