📄 executor.java
字号:
while (ifClause.size() != 0) {
/** 待执行为最后的else语句*/
if (ifClause.getFirst().equals("else 语句")) {
//获得执行语句块及嵌套层次
ifClause.removeFirst();
if (deepT.size() !=1) {
deepT = new LinkedList<Integer>(deepT.subList(1, deepT.size()));
startIndex = new ArrayList<Integer>(startIndex.subList(1, startIndex.size()));
endIndex = new ArrayList<Integer>(endIndex.subList(1, endIndex.size()));
//执行语句块
execute(ifClause, deepT, startIndex, endIndex);
}
break;
}
/** 布尔表达式返回值为true*/
else if (computeRelation (ifClause.get(1), startIndex.get(1), endIndex.get(1))) {
//计算执行语句结束位置
int end = new LinkedList<Integer>(deepT.subList(1, deepT.size())).indexOf(startDeep);
if (end == -1) end = deepT.size();
else end += 1;
//获得执行语句块及嵌套层次
ifClause = new LinkedList<String>(ifClause.subList(2, end));
if (deepT.size() != 2) {
deepT = new LinkedList<Integer>(deepT.subList(2, end));
startIndex = new ArrayList<Integer>(startIndex.subList(2, end));
endIndex = new ArrayList<Integer>(endIndex.subList(2, end));
//执行语句块
execute(ifClause, deepT, startIndex, endIndex);
}
break;
}
/** 布尔表达式返回值为false*/
else {
//计算执行语句结束位置
int end = new LinkedList<Integer>(
deepT.subList(1, deepT.size())).indexOf(startDeep);
//剩余待执行代码
if (end == -1) ifClause.clear();
else {
ifClause = new LinkedList<String>(ifClause.subList(end+1, ifClause.size()));
deepT = new LinkedList<Integer>(deepT.subList(end+1, deepT.size()));
startIndex = new ArrayList<Integer>(startIndex.subList(end+1, startIndex.size()));
endIndex = new ArrayList<Integer>(endIndex.subList(end+1, endIndex.size()));
}
}
}
}
/** read语句的执行*/
private void readExe (LinkedList<String> ifClause, int startIndex,
int endIndex) throws MyRuntimeException{
//提取变量
String str = ifClause.get(1);
int start = str.indexOf('[');
if (start == -1) {
//错误:变量未声明
if (!isDeclared (str)) throw new MyRuntimeException(
"变量 “" + str + "” 使用前未声明", startIndex, endIndex);
try {
/** int型变量值的读入*/
if (isIntDeclared (str)){
//获取输入
String inputT = JOptionPane.showInputDialog(null,
"请输入int型变量 “" + str + "” 的值").trim();
//检查是否正确的输入
for (char inputChar: inputT.toCharArray())
//错误:输入中含有错误字符
isStdInput(inputChar, false);
//消除输入中的空格
StringTokenizer tokenizer = new StringTokenizer(inputT, " ");
String input = "";
while (tokenizer.hasMoreTokens()) input += tokenizer.nextToken();
//设置变量的值
setIntVarValue (str, computeArithmetic(input, -3, -3));
}
/** 数组值的完整读入*/
else {
//获取输入
String inputT = JOptionPane.showInputDialog(null,
"请输入数组变量 “" + str + "” 的值");
//消除输入中的空格
StringTokenizer tokenizer = new StringTokenizer(inputT, " ");
String input = "";
while (tokenizer.hasMoreTokens()) input += tokenizer.nextToken();
if (isArrDeclared(input)) {
//错误:现有变量长度大于待赋值数组变量长度
if (getArrVar(input).length>getArrVar(str).length)
throw new MyRuntimeException("数组索引越界:" +
"数组变量 “" + str + "” 的长度:" + getArrVar(str).length +
" 输入数组变量 “" + input + "” 的长度:" + getArrVar(input).length,
-3, -3);
//设置变量的值
setArrVarValue(str, getArrVar(input));
}
else {
//输入内容包含在大括号内
if (input.length()>2 && input.charAt(0)=='{' && input.charAt(0)=='}')
input = input.substring(1, input.length()-1);
//检查是否正确的输入
for (char inputChar: input.toCharArray())
//错误:输入中含有错误字符
isStdInput(inputChar, true);
//分析输入的值
ArrayList<Integer> arrayList = computeArrayData(str, input, true, -3, -3);
//错误:输入数值个数超出数组变量长度
if (arrayList.size()>getArrVar(str).length)
throw new MyRuntimeException("数组索引越界: " +
"数组变量 “" + str + "” 的长度:" + getArrVar(str).length +
" 输入数值个数:" + arrayList.size(), -3, -3);
//设置变量的值
setArrVarValue(str, arrayList);
}
}
}
//错误:输入错误字符或数组索引越界
catch (MyRuntimeException e) {
throw e;
}
//错误:输入有误
catch (Exception e) {
throw new MyRuntimeException("错误的输入", -3, -3);
}
}
/** 对数组变量具体索引处的赋值*/
else {
String variable = str.substring(0, start);
String indexT = str.substring(start+1, str.length()-1);
int index = computeArithmetic (indexT, startIndex, endIndex);
//错误:索引越界
if (index<0 || index>=getArrVar(variable).length)
throw new MyRuntimeException("数组索引越界: " +
"数组变量 “" + variable + "” 的长度:" + getArrVar(variable).length +
" 错误的索引:" + index, startIndex, endIndex);
try {
//获取输入
String inputT = JOptionPane.showInputDialog(null,
"请输入数组变量 " + variable + " 索引 " + index + " 处的值");
//检查是否正确的输入
for (char inputChar: inputT.toCharArray())
//错误:输入中含有错误字符
isStdInput(inputChar, false);
//消除输入中的空格
StringTokenizer tokenizer = new StringTokenizer(inputT, " ");
String input = "";
while (tokenizer.hasMoreTokens()) input += tokenizer.nextToken();
//设置变量的值
setArrIndexValue (variable, index, computeArithmetic(input, startIndex, endIndex));
}
//错误:输入数值个数超出数组变量长度
catch (MyRuntimeException e) {
throw e;
}
//错误:输入有误
catch (Exception e) {
throw new MyRuntimeException("错误的输入", startIndex, endIndex);
}
}
}
/** 判断是否为正确输入的字符*/
private void isStdInput(char ch, boolean arr) throws MyRuntimeException{
String standard = "[]+-*/()_0123456789";
if (arr) standard += ",";
if ((ch >= 65 && ch <= 90) || (ch >= 97 && ch <= 122) ||
standard.indexOf(ch)!=-1) {}
else
throw new MyRuntimeException("输入中含有错误字符 “" + ch + "”", -3, -3);
}
/** 赋值语句的执行*/
private void evaluateExe (LinkedList<String> evaluateListT, int startIndex1,
int endIndex1, int startIndex2, int endIndex2) throws MyRuntimeException{
//提取待赋值变量
String str = evaluateListT.get(1);
String value = evaluateListT.get(2);
int end = str.indexOf('[');
//变量的赋值
if (end == -1) {
/** int型变量的赋值*/
if (isIntDeclared(str)) {
if (value.charAt(0) == '{')
throw new MyRuntimeException("不能将数据集赋值给int型变量 “" + str + "”",
startIndex2, endIndex2);
//设置变量的值
setIntVarValue(str, computeArithmetic(value, startIndex2, endIndex2));
}
/** 数组变量的赋值*/
else if (isArrDeclared(str)){
if (value.charAt(0)=='{')
setArrVarValue(str, computeArrayData(
str, value.substring(1, value.length()-1), true, startIndex2, endIndex2));
//错误:赋值的变量未声明
else if (!isDeclared(value)) throw new MyRuntimeException(
"变量 “" + value + "” 使用前未声明", startIndex2, endIndex2);
//错误:赋值的变量声明为int型
else if (!isArrDeclared(value)) throw new MyRuntimeException(
"不能将int型变量 “" + value + "” 赋值给数组变量 “" + str + "”",
startIndex2, endIndex2);
//设置变量的值
else {
try {
setArrVarValue(str, getArrVar(value));
}
catch (Exception e) {
throw new MyRuntimeException("数组索引越界: " +
"数组变量 “" + str + "” 的长度:" + getArrVar(str).length +
" 数组变量 “" + value + "” 的长度:" + getArrVar(value).length,
startIndex1, endIndex2);
}
}
}
//错误:待赋值变量未声明
else
throw new MyRuntimeException("变量 “" + str + "” 使用前未声明", startIndex1, endIndex1);
}
/** 数组变量具体索引处的赋值*/
else {
//获取变量
String variable = str.substring(0, end);
//错误:变量未声明
if (!isDeclared (variable)) throw new MyRuntimeException(
"变量 “" + variable + "” 使用前未声明", startIndex1, endIndex1);
//错误:变量为int型
else if (!isArrDeclared(variable)) throw new MyRuntimeException(
"对int型变量 “" + variable + "” 使用索引", startIndex1, endIndex1);
//计算索引
int index = computeArithmetic(str.substring(end+1, str.length()-1), startIndex1, endIndex1);
//错误:索引越界
if (index<0 || index>=getArrVar(variable).length)
throw new MyRuntimeException("数组索引越界: " +
"数组变量 “" + variable + "”的长度:" + getArrVar(variable).length +
" 错误的索引:" + index, startIndex1, endIndex1);
//计算表达式的值
int indexValue = computeArithmetic(value, startIndex2, endIndex2);
//对指定索引处赋值
setArrIndexValue (variable, index, indexValue);
}
}
/** 计算算术表达式的值
* 语法分析已保证格式正确
* String str 为算术表达式字符串*/
private int computeArithmetic (String str, int startIndex, int endIndex)
throws MyRuntimeException {
String strTemporary = str;
/** 循环消去括号*/
while (str.indexOf('[')+str.indexOf('(') != -2) {
//查找第一个括号开的位置
for (int i = 0; i <str.length(); i++) {
if (str.charAt(i)=='[' || str.charAt(i)=='(') {
/** 第一个括号开为中括号*/
if (str.charAt(i)=='[') {
//存储数组变量名开始位置
int start = -1;
for (int j = i; j >=0; j--) {
//查找变量开始位置
if ("+-*/".indexOf(str.charAt(j))!=-1) {
start = j;
break;
}
}
//获得的数组变量名
String var = str.substring(start+1, i);
//错误:变量未声明
if (!isDeclared(var)) throw new MyRuntimeException(
"变量 “" + var + "” 使用前未声明", startIndex, endIndex);
//错误:变量声明为int型
if (!isArrDeclared(var)) throw new MyRuntimeException(
"对int型变量 “" + var + "” 使用索引", startIndex, endIndex);
//计算对应括号闭位置
int endBracket = SyntaxAnalyze.analyzeBracket(str, '[', ']', i);
//递归计算索引值
int index = computeArithmetic(
str.substring(i+1, endBracket), startIndex, endIndex);
//错误:索引值越界
if (index < 0 || index >= getArrVar(var).length)
throw new MyRuntimeException("数组索引越界: " +
"数组变量 “" + var + "”的长度:" + getArrVar(var).length +
" 错误的索引:" + index, startIndex, endIndex);
//获取变量的值
int value = getArrVar(var).getValue(index);
//生成进行一次消括号后的串
String strT1 = (start==-1) ? "" : str.substring(0, start+1);
String strT2 = (endBracket==str.length()-1) ?
"" : str.substring(endBracket + 1, str.length());
str = strT1 + value + strT2;
}
/** 第一个括号开为小括号*/
else {
//计算对应括号闭位置
int endBracket = SyntaxAnalyze.analyzeBracket(str, '(', ')', i);
//递归计算小括号内的值
int value = computeArithmetic(
str.substring(i+1, endBracket), startIndex, endIndex);
//生成进行一次消括号后的串
String strT1 = (i==0) ? "" : str.substring(0, i);
String strT2 = (endBracket==str.length()-1) ?
"" : str.substring(endBracket+1, str.length());
str = strT1 + value + strT2;
}
break;
}
}
}
/** 循环消去乘除号*/
while (str.indexOf('*')+str.indexOf('/') != -2) {
//计算第一个乘除号位置
int location1 = str.indexOf('*'),location2 = str.indexOf('/');
int location = (location1*location2>0) ?
Math.min(location1, location2) : Math.max(location1, location2);
//计算第一个操作数的开始位置
int start = -1;
for (int i = location; i > start; i--) {
if ("+-".indexOf(str.charAt(i))!=-1) {
start = i;
if (str.charAt(i)=='-' && i!=0 && (str.charAt(i)=='+' || str.charAt(i)=='+'))
start = i-1;
break;
}
}
//获得第一个操作数的值及前面部分
String value1 = str.substring(start+1, location);
int number1 = getNumber(value1, startIndex, endIndex);
String strT1 = str.substring(0, start+1);
//计算第二个操作数的开始位置
int end = str.length();
for (int i = location+2; i < end; i++) {
if ("+-*/".indexOf(str.charAt(i))!=-1) {
end = i;
break;
}
}
//获得第二个操作数的值及后面部分
String value2 = str.substring(location+1, end);
int number2 = getNumber(value2, startIndex, endIndex);
String strT2 = (end == str.length()) ? "" : str.substring(end);
//计算乘除法
if (str.charAt(location) == '/' && number2==0) throw new MyRuntimeException(
"表达式 “" + strTemporary + "” 中含有除以0", startIndex, endIndex);
int number = (str.charAt(location) == '*') ? number1 * number2 : number1 / number2;
//生成进行一次乘除法后的串
str = strT1 + number + strT2;
}
/** 循环消去加减号*/
String strT = (str.length()==1)? "" : str.substring(1);
while (str.indexOf('+')+strT.indexOf('-') != -2) {
//以'+'号开始的串
if (str.indexOf('+')==0) {
str = str.substring(1);
strT = (str.length()==1)? "" : str.substring(1);
}
//以'-'号开始并且之后为计算中得到负数的
else if (str.charAt(0)=='-' && str.charAt(1)=='-') {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -