想了解更多内容,移步至编译原理专栏
2021.12.22 更新
整理了一下代码,同步到了gitee
https://gitee.com/godelgnis/lrparserhttps://gitee.com/godelgnis/lrparser
--------------------------------------------------分割线---------------------------------------------------------------------
在我一个实验的基础上,将代码进行修改,在语法分析的过程中进行语义分析,并将语义分析的结果打印出来。如果不想在分析过程中就把翻译后的句子打印出来,可以将分析好的每一个四元式先放进一个String数组,再将这个数组放到一个ArrayList中,等语法分析结束后,将动态数组中四元式打印出来。
测试的样例及结果
正确测试样例
begin a:=2+3*4; x:=(a+b)/c; end #
测试结果
错误测试样例
测试结果
由于在我之前的博客中我也已经给出了完整的源码,本次的实验仅仅是在之前代码的基础上进行修改,所以以下代码仅是一部分代码,有需要的朋友可以去我之前写过的几篇博客中去看一下,之后有空的话,再整理成专栏
词法分析器 Java完整代码版
语法分析器 Java版
语法分析器(二) 识别多错误 Java版
源代码:
public class IrParser {
private Analyzer analyzer;
private ArrayList<Word> list = new ArrayList<>();
private Word word;
private int index = 0; // 从列表中获取单词的下标
private boolean error = false; //标记是否检测到错误
public int rowNum = 1; //用来记录行数
private static int k = 1;
public IrParser() {
analyzer = new Analyzer("input.txt", "output.txt");
analyzer.analyze(analyzer.getContent());
list = analyzer.getList();
}
public void parse() {
if(list.size() > 0 && (word = getNext(list)).getTypenum() !=1) {
error = true;
index--;
System.out.print("begin错误");
System.out.println(" 识别符号为 " + word.getWord() + " " + "位置: " + rowNum + "行");
}
//分隔符
pretreatment();
if(list.size() > 0) {
word = getNext(list);
if (word == null) {
error = true;
System.out.print("缺end错误");
System.out.println(" 文件已结束 " + "位置: " + rowNum + "行");
}else if(word.getTypenum() != 6){
error = true;
System.out.print("缺end错误");
System.out.println(" 识别符号为 " + word.getWord() + " " + "位置: " + rowNum + "行");
}
}
if (!error) {
System.out.println("success");
}
}
/**
* 预处理
*/
public void pretreatment() {
statement();
while (word != null && word.getTypenum() != 6) {
statement();
}
index--;
}
/**
* 赋值错误和语句错误
*/
public void statement() {
String tt = null;
String eplace = null;
word = getNext(list);
if (word != null && word.getTypenum() != 26) {
switch (word.getTypenum()) {
case 10:
tt = word.getWord();
assignment(tt, eplace);
break;
default:
if (word.getTypenum() != 0 && word.getTypenum() != 6) {
error = true;
System.out.print("语句错误");
System.out.println(" 识别符号为 " + word.getWord() + " " + "位置: " + rowNum + "行");
if (null == tt) {
tt = "缺变量";
}
assignment(tt, eplace);
}
break;
}
}
}
/**
* 赋值号错误
*/
public String assignment(String tt, String eplace) {
word = getNext(list);
if (word != null ) {
if (word.getTypenum() == 18) {
eplace = expression();
System.out.println(tt + " = " + eplace );
} else {
error = true;
System.out.print("赋值号错误");
System.out.println(" 识别符号为 " + word.getWord() + " " + "位置: " + + rowNum + "行");
eplace = expression();
}
}
return eplace;
}
/**
* 分析表达式表达式
*/
public String expression() {
String tt;
String eplace = word.getWord();
String tp;
String ep2;
if (word.getTypenum() == 26)
return eplace;
word = getNext(list);
if (word != null) {
eplace = term();
while (word.getTypenum() == 13 || word.getTypenum() == 14) {
tt = word.getWord();
word = getNext(list);
ep2 = term();
tp = newTemp();
System.out.println(tp + " = " + eplace + " " + tt + " " + ep2);
eplace = tp;
}
}
return eplace;
}
public String term() {
String ep2;
String eplace = word.getWord();
String tp;
String tt;
if (word != null) {
eplace = factor();
while (word.getTypenum() == 15 || word.getTypenum() == 16) {
tt = word.getWord();
word = getNext(list);
ep2 = factor();
tp = newTemp();
System.out.println(tp + " = " + eplace + " " + tt + " " + ep2);
eplace = tp;
}
}
return eplace;
}
/**
* "("错误 和 表达式错误
*/
public String factor() {
String fplace = " ";
if (word != null) {
if (word.getTypenum() == 10 || word.getTypenum() == 11) {
fplace = word.getWord();
word = getNext(list);
} else if (word.getTypenum() == 27) {
fplace = expression();
if (word.getTypenum() == 28) {
word = getNext(list);
} else {
error = true;
System.out.print("')'错误");
System.out.println(" 识别符号为 " + word.getWord() + " " + "位置: " + rowNum + "行");
if (word.getTypenum() == 26)
return fplace;
word = getNext(list);
}
} else {
error = true;
System.out.print("表达式错误");
System.out.println(" 识别符号为 " + word.getWord() + " " + "位置: " + rowNum + "行");
if (word.getTypenum() == 26)
return "未知变量";
word = getNext(list);
}
}
return fplace;
}
/**
* 取下一个词,如果是读取到换行,就增加行数,
* @param list
* @return
*/
public Word getNext(ArrayList<Word> list) {
if (index < list.size()) {
Word currentWord = list.get(index++);
while (currentWord.getTypenum() == 30 || currentWord.getTypenum() == 31) {
//因为一个换行字符被我转换成长度为2字符串了,所以要除以2
rowNum += currentWord.getWord().length()/2;
currentWord = list.get(index++);
}
return currentWord;
} else {
return null;
}
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public static void main(String[] args) {
IrParser parser = new IrParser();
parser.parse();
}
public String newTemp() {
return "t"+(k++);
}
}