语法制导翻译 Java

    想了解更多内容,移步至编译原理专栏   

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++);
	}
}

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
语法制导翻译(Syntax-Directed Translation)是指在编译过程中,根据语法规则对语法结构进行分析,并在此基础上进行代码生成、优化等操作。生成四元式是其中的一种常见方法。 Java是一种面向对象编程语言,可以通过Java语言编写编译器或解释器。以下是一个简单的示例,演示如何使用Java语言实现一种语法制导翻译生成四元式的方法: 假设我们要处理的表达式包含加、减、乘、除四种运算符,以及整数和变量两种操作数。 1. 定义语法规则 首先,我们需要定义表达式的语法规则。例如,可以使用BNF(巴克斯-诺尔范式)表示法: ``` <expr> ::= <term> | <expr> + <term> | <expr> - <term> <term> ::= <factor> | <term> * <factor> | <term> / <factor> <factor> ::= <number> | <variable> <number> ::= <digit>+ <variable> ::= <letter> <alphanumeric>* <digit> ::= 0|1|2|3|4|5|6|7|8|9 <letter> ::= a|b|c|...|z|A|B|C|...|Z <alphanumeric> ::= <letter> | <digit> ``` 2. 定义语义规则 接下来,我们需要定义如何将语法结构转化为四元式。例如,对于加法操作,可以使用如下的语义规则: ``` <expr> ::= <term> { $$ = $1; } | <expr> + <term> { $$ = new Quadruple("+", $1, $3, new Temp()); } | <expr> - <term> { $$ = new Quadruple("-", $1, $3, new Temp()); } ``` 其中,`$$`表示当前语法结构的值,`$1`、`$2`、`$3`等表示该语法结构的子结构的值。在这个例子中,`$1`表示`<term>`的值,`$3`表示`<term>`的值,`new Quadruple("+", $1, $3, new Temp())`表示生成一个加法四元式,并将其结果赋值给`$$`。 3. 实现编译器 最后,我们需要实现一个编译器,将表达式转化为四元式。例如,可以使用Java语言实现一个递归下降分析器: ``` public Quadruple compile(String input) { lexer.setInput(input); return expr(); } private Quadruple expr() { Quadruple t = term(); if (lexer.peek().getType() == TokenType.PLUS) { lexer.nextToken(); Quadruple e = expr(); return new Quadruple("+", t, e, new Temp()); } if (lexer.peek().getType() == TokenType.MINUS) { lexer.nextToken(); Quadruple e = expr(); return new Quadruple("-", t, e, new Temp()); } return t; } private Quadruple term() { Quadruple f = factor(); if (lexer.peek().getType() == TokenType.TIMES) { lexer.nextToken(); Quadruple t = term(); return new Quadruple("*", f, t, new Temp()); } if (lexer.peek().getType() == TokenType.DIVIDE) { lexer.nextToken(); Quadruple t = term(); return new Quadruple("/", f, t, new Temp()); } return f; } private Quadruple factor() { Token token = lexer.nextToken(); if (token.getType() == TokenType.NUMBER) { return new Quadruple(token.getValue(), null, null, new Temp()); } if (token.getType() == TokenType.VARIABLE) { return new Quadruple(token.getValue(), null, null, new Temp()); } throw new IllegalArgumentException("Invalid factor: " + token); } ``` 其中,`compile`方法接受一个字符串类型的表达式,返回一个四元式。`expr`、`term`、`factor`方法分别对应语法规则中的`<expr>`、`<term>`、`<factor>`。在这个例子中,`Quadruple`表示一个四元式,`Temp`表示一个临时变量。 这是一个简单的示例,实际的编译器会更加复杂。但是,这个示例可以帮助我们理解语法制导翻译生成四元式的基本思路。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值