📄 compiler.java
字号:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.lang.*;
import java.util.*;
public class Compiler extends Frame implements ActionListener{
int row = 1;//数排列,横坐标
int line = 1;//横排行,竖坐标。当遇到回车换行的时候,line++,row = 0;
boolean lexical_checked = false;
ArrayList styleStr = new ArrayList();//tokens的类型
ArrayList programStr = new ArrayList();//程序的各个实际标志符
ArrayList styleStack = new ArrayList();//符号栈
ArrayList stateStack = new ArrayList();//状态栈,符号栈与状态栈同时变化,长度始终相同。
MenuBar mb = new MenuBar();
Menu fileMenu = new Menu("File");
Menu actionMenu = new Menu("Project");
MenuItem closeWindow = new MenuItem("Exit");
MenuItem openFile = new MenuItem("Open file");
MenuItem lexical_check = new MenuItem("Check Lex");
MenuItem syntax_check = new MenuItem("Check Syntax");
int begin = 0;//当读到第一个字母的时候,标志其位置
int end = 0;
int num_begin = 0;//标志数字首位开始标志
int num_end = 0;//标志数字末尾表示标志
TextArea text = new TextArea(25,60);
TextArea error_text = new TextArea(10,60);
FileDialog file_dialog_load = new FileDialog(this, "Open file...", FileDialog.LOAD);
Compiler(){
this.setLayout(new FlowLayout());
this.setMenuBar(mb);
mb.add(fileMenu);
mb.add(actionMenu);
fileMenu.add(openFile);
fileMenu.add(closeWindow);
actionMenu.add(lexical_check);
actionMenu.add(syntax_check);
this.add(text);
this.add(error_text);
error_text.setText("Lexical Information: \n");
closeWindow.addActionListener(this);
openFile.addActionListener(this);
lexical_check.addActionListener(this);
syntax_check.addActionListener(this);
this.setSize(500, 600);
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
this.setVisible(true);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Compiler compiler = new Compiler();
}
public void actionPerformed(ActionEvent e){
if(e.getSource() == closeWindow){
System.exit(0);
}else if(e.getSource() == openFile){
file_dialog_load.setVisible(true);
File myfile = new File(file_dialog_load.getDirectory(), file_dialog_load.getFile());
try{
BufferedReader bufReader = new BufferedReader(new FileReader(myfile));
String content = "";
String str;
while((str = bufReader.readLine()) != null){
content += str + "\n";
text.setText(content);
}
}catch(IOException ie){
error_text.appendText("IOexception occurs...");
}
}else if(e.getSource() == lexical_check){
//error_text.setText("Lexical Information: \n");
error_text.setText("");
row = 0;
line = 1;
checkLexical();
lexical_checked = true;
}else if(e.getSource() == syntax_check){
if(lexical_checked == false){
error_text.appendText("You have not checked the lexical! \n");
}else{
check_syntax();
}
}
}
/*
* 对Text区域数据区进行词法检测
* */
public void checkLexical(){
/***********************************/
styleStr.clear();
programStr.clear();
styleStack.clear();
stateStack.clear();
/***********************************/
String error_info = error_text.getText();
String content = text.getText();
if(content.equals("")){
error_info += "Text is empty! You havn't input any code!\n";
error_text.setText(error_info);
}
else{
int i = 0;//选择第i个字符进行检测。
int N = content.length();
int state = 0;//状态标志
for(i = 0; i < N; i++){//对所有字符进行检测
row++;
char c = content.charAt(i);
switch(state){
case 0:
//row++;
if(c == ',' || c == ' ' || c == '\t' || c == '{' || c =='}' || c == '(' || c == ')' || c == ';' || c == '[' || c == ']') {
if(isDigit(content.charAt(i - 1)) && isDigit(content.charAt(begin))){
end = i;
error_text.append("info: 数值表达式 " + content.substring(begin, end) + '\n');
}
/******new*****/
if(c == ',' || c == '{' ||c == '}'||c == '(' ||c == ')'|| c == ';'){
String str = "" + c;
programStr.add(str);
styleStr.add(str);
}
state = 0;
}
else if(c == '+') state = 1;
else if(c == '-') state = 2;
else if(c == '*') state = 3;
else if(c == '/') state = 4;
else if(c == '!') state = 5;
else if(c == '>') state = 6;
else if(c == '<') state = 7;
else if(c == '=') state = 8;
else if(c == '\n') state = 9;//输入为回车
else if(isLetter(c)) {
state = 10;
begin = i;
}
else if(isDigit(c)) {
begin = i;
state = 11;
}
else if(c == '#') state = 12;
else if(c == '&') state = 14;
else if(c == '|') state = 15;
else if(c == '"') state = 16;
else error_text.appendText("line: " + line + " row: " + row + " error: '" + c + "' Undefined character! \n");
break;
case 1://标志符是 +
//row++;
if(c == '+'){
state = 0;
error_text.appendText("info: 运算符 '++'\n");
/***new**/
programStr.add("++");
styleStr.add("++");
}
else if(c == '='){
state = 0;
error_text.appendText("info: 运算符 '+='\n");
/***new**/
programStr.add("+=");
styleStr.add("+=");
}else{
state = 0;
error_text.appendText("info: 运算符 '+'\n");
/***new**/
programStr.add("+");
styleStr.add("+");
i--;
row--;
}
break;
case 2://标志符是 -
if(c == '-'){
error_text.appendText("info: 运算符 '--'\n");
/***new**/
programStr.add("--");
// styleStr.add("--")
}
else if(c == '=') {
error_text.appendText("info: 运算符 '-='\n");
/***new**/
programStr.add("=");
styleStr.add("=");
}
else{
error_text.appendText("info: 运算符 '-'\n");
/***new**/
programStr.add("-");
styleStr.add("-");
i--;
row--;
}
state = 0;
break;
case 3://标志符是 *
if(c == '='){
error_text.appendText("info: 运算符 '*='\n");
/***new**/
programStr.add("*=");
styleStr.add("*=");
}
else{
error_text.appendText("info: 运算符 '*'\n");
/***new**/
programStr.add("*");
styleStr.add("*");
i--;
row--;
}
state = 0;
break;
case 4://标志符是 /
if(c == '/'){
while((c) != '\n'){
c = content.charAt(i);
i++;
}
state = 0;
error_text.appendText("info: 注释部分 // \n");
}else if(c == '='){
state = 0;
error_text.appendText("info: 运算符 /= \n");
/***new**/
programStr.add("/=");
styleStr.add("/=");
}else{
state = 0;
error_text.appendText("info: 运算符 / \n");
/***new**/
programStr.add("/");
styleStr.add("/");
i--;
row--;
}
//state = 0;
break;
case 5://标志符是 !
if(c == '='){
error_text.appendText("info: 运算符 != \n");
/***new**/
programStr.add("!=");
styleStr.add("!=");
state = 0;
}else{
state = 0;
i--;
row--;
error_text.appendText("info: 运算符 ! \n");
/***new**/
programStr.add("!");
styleStr.add("!");
}
//state = 0;
break;
case 6://标志符是 >
if(c == '='){
error_text.appendText("info: 运算符 >= \n");
/***new**/
programStr.add(">=");
styleStr.add(">=");
state = 0;
}else{
i--;
state = 0;
error_text.appendText("info: 元算符 > \n");
/***new**/
programStr.add(">");
styleStr.add(">");
}
//state = 0;
break;
case 7://标志符是 <
if(c == '='){
error_text.appendText("info: 运算符 <= \n");
/***new**/
programStr.add("<=");
styleStr.add("<=");
state = 0;
}else{
i--;
state = 0;
error_text.appendText("info: 运算符 < \n");
/***new**/
programStr.add("<");
styleStr.add("<");
}
break;
case 8://标志符是 =
if(c == '='){
error_text.appendText("info: 运算符 == \n");
/***new**/
programStr.add("==");
styleStr.add("==");
state = 0;
}else{
state = 0;
error_text.appendText("info: 运算符 = \n");
/***new**/
programStr.add("=");
styleStr.add("=");
}
break;
case 9://标志符是 回车
state = 0;
row = 1;
line ++;
i--;//诡异啊!这里竟然要减一才能正常的忽略回车!
break;
case 10://标志符是 字母
if(isLetter(c) || isDigit(c)){
state = 10;
}else{
end = i;
String id = content.substring(begin, end);
if(isKey(id)){
error_text.appendText("info: 关键字 " + id + '\n');
if(id.equals("if")||id.equals("else")||id.equals("for")||id.equals("while")||id.equals("do")||id.equals("repeat")||id.equals("until")
||id.equals("read")||id.equals("write")||id.equals("return")||id.equals("to")){
styleStr.add(id);
}else if(id.equals("int")||id.equals("real")||id.equals("boolean")){
styleStr.add("type");
}else
styleStr.add("C");
}
else{
error_text.appendText("info: 标志符 " + id + '\n');
styleStr.add("C");
}
/***new**/
programStr.add(id);
i--;
row--;
state = 0;
}
//state = 0;
break;
case 11://标志符是 数字
if(c == 'e' || c == 'E')
state = 13;
else if(isDigit(c) || c == '.'){
//省略跳过,i加一操作
}else {
if(isLetter(c)){
error_text.appendText("error: line " + line + " row " + row + " 数字格式错误或者标志符错误\n");
}
end = i;
String id = content.substring(begin, end);
/***new**/
programStr.add(id);
styleStr.add("K");
//i--;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -