Java实现C的语法分析器(预测分析法)

本文介绍了作者使用Java实现C语言的LL(1)语法分析器的过程,详细讨论了自顶向下分析法、预测分析表的构造、FIRST集和FOLLOW集的计算,以及错误处理策略。在实现过程中,作者遇到了左递归和右递归问题,并给出了相应的解决方案。文章最后分享了项目的源代码供读者参考。
摘要由CSDN通过智能技术生成

         在上一次词法分析的基础之上,我完成了我的C语言的语法分析器。这次选择的是用Java来实现,采用了自顶向下的分析方法,其思想是根据输入token串的最左推导,试图根据现在的输入字符来判断用哪个产生式来进行推导。

         使用LL(1)分析法的问题就是对文法的要求较高,要求消除回溯了左递归,以致于后来在写文法的时候遇到各种麻烦,做了各种消除(本来想偷个懒,不通过程序直接手动解决这个问题的,结果还是耗费了不少体力)。

         预测分析法的关键在于预测分析表的构造。这就要求求出每个变量的FIRST集和FOLLOW集,并且根据这来求出每个产生式的SELECT集。所以只要在顺利的理解了求解非终结符的FIRST集和FOLLOW集的算法之后,语法分析的实现其实已经胜利在望了。


图1.求FIRST集的算法

	/**
	 * 初始化First集
	 * 
	 * @param expList
	 * @param mFirst
	 */
	public static List<String> initFirst(List<Grammar> expList,
			List<String> mFirst) {
		List<String> right = null;
		for (int i = 0; i < expList.size(); i++) { // 初始化FIRST集
			right = expList.get(i).getRightPart();
			if (right.size() > 0) {
				if (terminalSymbolMap.containsKey(right.get(0))) { // 若右部表达式的第一位为终结符则加入nts的FIRST集
					mFirst.add(right.get(0));
				}
			}
		}
		return mFirst;
	}


/**
	 * 求非终结符的FIRST集
	 * 
	 * @param nts
	 *            非终结符
	 * @return FIRST集
	 */
	public static List<String> FIRST(NonTerminalSymbol nts) {
		List<Grammar> expList = getMyExp(nts.getValue());
		List<String> mFirst = new ArrayList<String>();
		List<String> right = null;

		mFirst = initFirst(expList, mFirst);// 初始化工作

		for (int i = 0; i < expList.size(); i++) {
			right = expList.get(i).getRightPart();
			if (right.size() > 0) {
				if (nonTerminalSymbolMap.containsKey(right.get(0))) {// 若右部表达式的第一位为非终结符则递归
					combineList(mFirst,
							FIRST(new NonTerminalSymbol(right.get(0))));

					int j = 0;
					while (j < right.size() - 1 && isEmptyExp(right.get(j))) { // 若X→Y1…Yn∈P,且Y1...Yi-1⇒*ε,
						combineList(mFirst,
								FIRST(new NonTerminalSymbol(right.get(j + 1))));
						j++;
					}
				}
			}
		}
		if (mFirst.contains("$"))
			mFirst.remove("$");
		combineList(nts.getFirst(), mFirst);
		return mF
  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 51
    评论
评论 51
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值