public Principal() {
		arquivo = new Arquivo();
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent ife) {
				sair();
			}
		});
		setBounds(100, 100, 450, 300);
		updateTitle();

		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);

		JMenu mnArquivo = new JMenu("Arquivo");
		JMenuItem mntmNovo = new JMenuItem("Novo");
		JMenuItem mntmAbrir = new JMenuItem("Abrir");
		JSeparator sep1 = new JSeparator();
		JMenuItem mntmSalvar = new JMenuItem("Salvar");
		JMenuItem mntmSalvarComo = new JMenuItem("Salvar Como");
		JSeparator sep2 = new JSeparator();
		JMenuItem mntmSair = new JMenuItem("Sair");

		JMenu mnAnalise = new JMenu("Análise");
		JMenuItem mntmLexica = new JMenuItem("Léxica");
		JMenuItem mntmSintatica = new JMenuItem("Sintática");
		JMenuItem mntmSemantica = new JMenuItem("Semântica");

		mntmNovo.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				arquivo.resetCurrentFile();
				textArea.setText("");
				updateTitle();
			}
		});

		mntmAbrir.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (confirmarContinuarDocModificado("abrir outro documento")) {
					textArea.setText(arquivo.abrir());
					atualizarInfoArquivo();
				}
			}
		});

		mntmSalvar.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (arquivo.salvar(textArea.getText())) {
					atualizarInfoArquivo();
				}
			}
		});

		mntmSalvarComo.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (arquivo.salvarComo(textArea.getText())) {
					atualizarInfoArquivo();
				}
			}
		});

		mntmSair.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				sair();
			}
		});

		mntmLexica.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					Analisador.lexico(textArea.getText());
					OptionPane.messageInformation("Não há problemas léxicos no programa", "Sucesso");
				} catch (AnalysisError e1) {
					tratarExcecao(e1);
				}
			}
		});

		mntmSintatica.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					Analisador.sintatico(textArea.getText());
					OptionPane.messageInformation("Não há problemas léxicos ou sintáticos no programa", "Sucesso");
				} catch (AnalysisError e1) {
					tratarExcecao(e1);
				}
			}
		});

		mntmSemantica.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					Analisador.semantico(textArea.getText());
					OptionPane.messageInformation("Não há problemas léxicos, sintáticos ou semânticos no programa", "Sucesso");
				} catch (AnalysisError e1) {
					tratarExcecao(e1);
				}
			}
		});

		menuBar.add(mnArquivo);
		mnArquivo.add(mntmNovo);
		mnArquivo.add(mntmAbrir);
		mnArquivo.add(sep1);
		mnArquivo.add(mntmSalvar);
		mnArquivo.add(mntmSalvarComo);
		mnArquivo.add(sep2);
		mnArquivo.add(mntmSair);

		menuBar.add(mnAnalise);
		mnAnalise.add(mntmLexica);
		mnAnalise.add(mntmSintatica);
		mnAnalise.add(mntmSemantica);

		JMenu mnTestes = new JMenu("Testes");
		menuBar.add(mnTestes);

		JMenuItem mntmTestes = new JMenuItem("Realizar testes");
		mntmTestes.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				String resultado = Teste.realizarTestes();

				if (resultado.length() == 0) {
					OptionPane.messageInformation("Testes realizados com sucesso", "Resultado dos testes");
				} else {
					OptionPane.messageError("Os seguintes problemas ocorreram durantes os testes: \n" + resultado, "Resultado dos testes");
				}
			}
		});
		mnTestes.add(mntmTestes);

		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);

		JScrollPane scrollPane = new JScrollPane();
		contentPane.add(scrollPane, BorderLayout.CENTER);

		textArea = new JTextArea();
		scrollPane.setViewportView(textArea);

		// Monitora mudanças no documento
		documentoAlterado = false;
		textArea.getDocument().addDocumentListener(new DocumentListener() {
			@Override
			public void removeUpdate(DocumentEvent e) {
				documentoAlterado = true;
			}

			@Override
			public void insertUpdate(DocumentEvent e) {
				documentoAlterado = true;
			}

			@Override
			public void changedUpdate(DocumentEvent arg0) {
				documentoAlterado = true;
			}
		});
	}