📄 syntaxanalyze.java
字号:
char bracket = '5';
if (str.charAt(start) == '6') bracket = '7';
//括号闭第一次出现的位置
int endT = str.indexOf(bracket);
//错误:括号闭出现于括号开之前
if (start>endT||endT==start+1) return false;
//括号开、闭的计数及括号闭位置
int end = analyzeBracket(str, str.charAt(start), bracket, start);
//错误:括号内为错误的算术表达式
if (arithmetic(str.substring(start+1,end))==false) return false;
//将括号部分替换
String strT1 = "";
//第一个括号开为小括号
if (str.charAt(start)=='4')
strT1= (start==0) ? "" : str.substring(0,start);
//第一个括号开为中括号
else
strT1= (start==1) ? "" : str.substring(0,start-1);
//对应括号闭之后的字符串
String strT2= (end==str.length()-1) ? "" : str.substring(end+1);
//去掉第一对括号后的字符串
str=strT1 + "0" + strT2;
}
//将字符串中表示数字与变量的部分统一
str = str.replace('0', '1');
//对不含有括号的待分析内容使用正则表达式进行匹配
if (Pattern.matches("2?+1+(21|31)*", str)) return true;
return false;
}
//关系运算
//具体编码与arithmeticOperation方法编码相同以保证直接调用arithmetic方法
private boolean relationOperation(LinkedList<Tokens> listT,
DefaultMutableTreeNode booleanTree) {
//存储待分析内容
String str1 = "";
//存储经过格式转化之后的待分析内容
String str2 = "";
//括号开、闭的个数
int count1 = 0, count2 = 0;
int count3 = 0, count4 = 0;
//依次编码(算术表达式所含有内容编码不变)
for (Tokens value: listT) {
str1 += value.token;
//待分析为数字
if (value.type == CMMN) str2+=0;
//待分析为标志符
else if (value.type == CMMI) str2+=1;
//待分析为"+"或"-"
else if (value.token.equals("+") || value.token.equals("-")) str2+=2;
//待分析为"*"或"/"
else if (value.token.equals("*") || value.token.equals("/")) str2+=3;
//待分析为"("
else if (value.token.equals("(")) {
str2+=4; count1++;
}
//待分析为")"
else if (value.token.equals(")")) {
str2+=5; count2++;
}
//待分析为"["
else if (value.token.equals("[")) {
str2+=6;count3++;
}
//待分析为"]"
else if (value.token.equals("]")) {
str2+=7;count4++;
}
//待分析为"<"或">"
else if (value.token.equals("<")||value.token.equals(">"))
str2+=8;
//待分析为"<>"或"=="
else if (value.token.equals("<>")||value.token.equals("=="))
str2+=9;
//待分析为"real"
else if (value.token.equals("real"))
str2+="t";
//待分析为其他内容
else {
syntaxWrongOutput.add(" 关系表达式含有错误的内容");
tokenErrorStart.add(value.start);
tokenErrorEnd.add(value.end);
return false;
}
}
//长度限制
if (listT.size()<3) {
syntaxWrongOutput.add(" 关系表达式:" + str1 + " 错误 #" + listT.getFirst().lineNo);
tokenErrorStart.add(listT.getFirst().start);
tokenErrorEnd.add(listT.getLast().end);
return false;
}
//括号开、闭的个数不同
if (count1!=count2 || count3!=count4) {
syntaxWrongOutput.add(" 关系表达式括号无法匹配");
tokenErrorStart.add(listT.getFirst().start);
tokenErrorEnd.add(listT.getLast().end);
return false;
}
//进行关系表达式的分析
//分析结果为错误
if (relation(str2) == false) {
syntaxWrong();
syntaxWrongOutput.add(" 关系表达式:" + str1 + " 错误 #" + listT.getFirst().lineNo);
tokenErrorStart.add(listT.getFirst().start);
tokenErrorEnd.add(listT.getLast().end);
return false;
}
//分析结果为正确
else {
//添加子节点及输出
DefaultMutableTreeNode booleanTreeT = new DefaultMutableTreeNode("关系表达式: " + str1);
booleanTree.add(booleanTreeT);
syntaxOutput.add(showSpace() + "关系表达式: " + str1 + " #" + listT.getFirst().lineNo );
tokenRightStart.add(listT.getFirst().start);
tokenRightEnd.add(listT.getLast().end);
deep.add(countSpace);
return true;
}
}
//分析关系表达式
private boolean relation(String str) {
//生成不含括号的串
//含有小括号或中括号时
while (str.indexOf('4') + str.indexOf('6')!=-2) {
//长度限制
if (str.length()==2)return false;
//括号开第一次出现的位置
int start = -1;
for (int i =0; i < str.length(); i++) {
if (str.charAt(i)=='4' || str.charAt(i)=='6') {
start = i;
if (str.charAt(i)=='6' && (i==0||!(str.charAt(i-1)=='1'))) {
return false;
}
break;
}
}
//对应的括号闭
char bracket = '5';
if (str.charAt(start) == '6') bracket = '7';
//括号闭第一次出现的位置
int endT = str.indexOf(bracket);
//错误:括号闭出现于括号开之前
if (start>endT||endT==start+1) return false;
//括号开、闭的计数及括号闭位置
int end = analyzeBracket(str, str.charAt(start), bracket, start);
//括号内内容的编码
String type = "";
if (str.charAt(start) == '4') {
//括号内为算术表达式
if (arithmetic(str.substring(start+1,end))) type = "0";
//括号内为关系表达式
else if (relation(str.substring(start+1,end))) type = "t";
//括号内为其他
else return false;
}
else {
//正确的数组索引
if (arithmetic(str.substring(start+1,end))) type = "0";
//错误的数组索引
else return false;
}
//将括号部分替换
String strT1="";
//第一个括号开为小括号
if (str.charAt(start)=='4')
strT1= (start==0) ? "" : str.substring(0,start);
//第一个括号开为中括号
else
strT1= (start==1) ? "" : str.substring(0,start-1);
//括号闭之后部分
String strT2= (end==str.length()-1) ? "" : str.substring(end+1);
//去掉第一对括号后的字符串
str=strT1 + type + strT2;
}
//含有real或者括号内计算得出关系表达式值
if (str.contains("t")) {
if (str.equals("t9t")||str.equals("t")) return true;
}
else {
//长度限制
if (str.length() <= 2)return false;
int location1 = str.indexOf('8');
int location2 = str.indexOf('9');
//不能同时含有两类关系运算符
if (location1 * location2 < 0 ) {
//第一次出现关系运算符的位置
int location = Math.max(location1, location2);
//关系运算符不能位于开始或者结束位置
if (location == 0 || location == str.length()-1) return false;
//关系运算符前后均为正确的算数表达式
if (arithmetic(str.substring(0, location)) && arithmetic(str.substring(location+1)))
return true;
}
}
return false;
}
//错误输出:含有语法错误
private void syntaxWrong() {
if (syntaxError == false) {
syntaxWrongOutput.add("含有语法错误:");
tokenErrorStart.add(-2);
tokenErrorEnd.add(-2);
}
syntaxError = true;
}
//错误输出:关键字使用有误
private void keywordUseWrong(Tokens token) {
syntaxWrong();
syntaxWrongOutput.add("关键字 " + token.token + " 使用有误 #" + token.lineNo);
tokenErrorStart.add(token.start);
tokenErrorEnd.add(token.end);
}
//错误输出:变量声明有误
private void declareWrong(Tokens token) {
syntaxWrong();
syntaxWrongOutput.add("没有正确声明变量 " + token.token + " #" + token.lineNo);
tokenErrorStart.add(token.start);
tokenErrorEnd.add(token.end);
}
//错误处理:语句错误
//boolean needOut 是否需要输出
private LinkedList<Tokens> statementWrong(LinkedList<Tokens> listT, boolean needOut) {
syntaxWrong();
//无法进行后续分析
boolean wrongOccer = true;
//错误是否已经输出
boolean wrongOut = false;
//备份需输出内容
Tokens tokenT = listT.getFirst();
for (int i = 0; i < listT.size(); i++) {
//遇到";"或者保留字结束分析,并设置待后续分析的内容
if (listT.get(i).token.equals(";") || listT.get(i).type==CMMK) {
wrongOccer = false;
if (listT.get(i).token.equals(";")) {
//剩余待分析内容
if (i != listT.size()-1)
listT = new LinkedList<Tokens>(listT.subList(i+1, listT.size()));
else listT.clear();
}
else {
//剩余待分析内容
if (i != listT.size()-1)
listT = new LinkedList<Tokens>(listT.subList(i, listT.size()));
else {
keywordUseWrong(listT.get(i));
listT.clear();
}
}
break;
}
}
//输出分析结果
if (wrongOccer == true || wrongOut == false) {
if (needOut == true) {
syntaxWrongOutput.add("语句不能以 " + tokenT.token + " 开始 #" + tokenT.lineNo);
tokenErrorStart.add(tokenT.start);
tokenErrorEnd.add(tokenT.end);
}
if (wrongOccer == true)
listT.clear();
}
return listT;
}
//错误处理:没有if语句的else及else if语句
private void elseBlockWrong(LinkedList<Tokens> listT, boolean executeTimes) {
//输出错误
keywordUseWrong(listT.getFirst());
syntaxWrongOutput.add(" 错误原因 :缺少 if 语句");
tokenErrorStart.add(listT.getFirst().start);
tokenErrorEnd.add(listT.getFirst().end);
//单独的else
if (list.size()==1)
listT.clear();
else {
//else后含有block
if (listT.get(1).token.equals("{")) {
//计算对应结束括号位置
int end = analyzeBracket(listT, "{", "}", 1);
//括号部分未结束
if (end == -1) {
syntaxWrongOutput.add(" 括号无法匹配 #" + listT.get(1).lineNo);
tokenErrorStart.add(listT.get(1).start);
tokenErrorEnd.add(listT.get(1).end);
//移除"else"及"{"
listT.removeFirst();
listT.removeFirst();
//对剩余内容进行分析
syntaxAnalyze(new DefaultMutableTreeNode(), listT, true);
listT.clear();
}
else {
//分析括号内内容
syntaxAnalyze(new DefaultMutableTreeNode(),
new LinkedList<Tokens>(listT.subList(2, end)), true);
//剩余待分析内容
if (end==listT.size()-1) listT.clear();
else listT = new LinkedList<Tokens>(listT.subList(end+1, listT.size()));
}
}
//else后为if移除"else"之后进行一次分析
else if (listT.get(1).token.equals("if")){
listT.removeFirst();
keywordMatch(listT, new DefaultMutableTreeNode(), false);
listT = listTT;
}
//其他
else {
listT.removeFirst();
listT = statementWrong(listT, false);
}
}
//进入后续分析或分析结束并备份剩余待分析内容
if (executeTimes)
matchingAnalyze(listT, new DefaultMutableTreeNode(), true);
else listTT = listT;
}
//空格输出
public String showSpace(){
String space = "";
for (int i = 0; i < countSpace; i++)
space += " ";
return space;
}
//语法分析输出
public ArrayList<String> toArrayList(){
//词法分析发现错误
if (lexicalError == true) return super.toArrayList();
//语法分析发现错误
if (syntaxError == true) return syntaxWrongOutput;
return syntaxOutput;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -