java实现消除文法的左递归

package com.siwanghu.syntaxanalyzer.bean;

public class Grammar {
	private String left;
	private String right;
	private int id;
	private static int ID = 0;

	public Grammar() {
		super();
		id = ID++;
	}

	public Grammar(String left, String right) {
		super();
		this.left = left;
		this.right = right;
		id = ID++;
	}

	public String getLeft() {
		return left;
	}

	public void setLeft(String left) {
		this.left = left.replace(" ", "");
	}

	public String getRight() {
		return right;
	}

	public void setRight(String right) {
		this.right = right.replace(" ", "");
	}

	public int getId() {
		return id;
	}

	@Override
	public String toString() {
		return "Grammar [left=" + left + ", right=" + right + "]";
	}

}
package com.siwanghu.syntaxanalyzer.algorithm;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

import com.siwanghu.syntaxanalyzer.bean.Grammar;

public class Production {
	private List productions = new LinkedList();       //产生式
	private List symbols = new ArrayList();        //初始产生式非终结符
	private List nonTerminatingSymbol = new ArrayList(); //LL(1)文法非终结符
	private List terminatingSymbol = new ArrayList();    //LL(1)文法终结符

	public Production(List productions) {
		super();
		this.productions = productions;
		symbolProductions();
	}

	public List getProductions() {
		return productions;
	}

	public List getSymbols() {
		return symbols;
	}

	public List getNonTerminatingSymbol(){
		return nonTerminatingSymbol;
	}

	public List getTerminatingSymbol(){
		return terminatingSymbol;
	}
    
	public void removeLeftRecursion() {
		for (int i = 0; i < symbols.size(); i++) {
			for (int j = 0; j < i; j++) {
				iterativeReplacement(symbols.get(i), symbols.get(j));
			}
			removeLeftRecursion(symbols.get(i));
		}
		no_or_is_terminatingSymbol();
	}

	private void symbolProductions() {
		if (productions.size() != 0) {
			for (int i = 0; i < productions.size(); i++) {
				if (!((ArrayList) symbols).contains(productions
						.get(i).getLeft().charAt(0))) {
					symbols.add(productions.get(i).getLeft().charAt(0));
				}
			}
		}
	}

	private void no_or_is_terminatingSymbol() {
		for (int i = 0; i < productions.size(); i++) {
			if (!((ArrayList) nonTerminatingSymbol)
					.contains(productions.get(i).getLeft())) {
				nonTerminatingSymbol.add(productions.get(i).getLeft());
			}
			if (productions.get(i).getLeft() == productions.get(i).getLeft()
					.charAt(0)
					+ "‘") {
				nonTerminatingSymbol.add(productions.get(i).getLeft());
			}
		}
		for (int i = 0; i < productions.size(); i++) {
			String temp = productions.get(i).getRight();
			temp = temp.replace("epsilon", "#");
			for (int j = 0; j < nonTerminatingSymbol.size(); j++) {
				temp = temp.replaceAll(nonTerminatingSymbol.get(j), "");
			}
			temp = temp.replaceAll("\\\\|", "");
			temp = temp.replaceAll("‘", "");
			char[] chars = temp.toCharArray();
			for (int k = 0; k < chars.length; k++) {
				if (chars[k] == ‘#‘) {
					if (!terminatingSymbol.contains("epsilon")) {
						terminatingSymbol.add("epsilon");
					}
				} else {
					if (!terminatingSymbol.contains(String.valueOf(chars[k]))) {
						terminatingSymbol.add(String.valueOf(chars[k]));
					}
				}
			}
		}
	}

	private void iterativeReplacement(Character left, Character right) {
		ListIterator listIterator = productions.listIterator();
		while (listIterator.hasNext()) {
			String inRight = "";
			Grammar grammar = listIterator.next();
			if (grammar.getLeft().equals(left.toString())) {
				boolean isReplacement = false;
				String[] rights = grammar.getRight().split("\\\\|");
				for (int i = 0; i < rights.length; i++) {
					if (rights[i].startsWith(right.toString())) {
						isReplacement = true;
					}
				}
				if (isReplacement) {
					ListIterator _listIterator = productions
							.listIterator();
					while (_listIterator.hasNext()) {
						Grammar _grammar = _listIterator.next();
						if (_grammar.getLeft().equals(right.toString())) {
							String[] _rights = _grammar.getRight().split("\\\\|");
							for (int i = 0; i < rights.length; i++) {
								boolean isCheck = false;
								if (rights[i].startsWith(right.toString())) {
									isCheck = true;
									for (int j = 0; j < _rights.length; j++) {
										String temp = rights[i];
										inRight += (temp.replaceFirst(
												right.toString(), _rights[j]) + "|");
									}
								}
								if (!isCheck) {
									inRight += (rights[i] + "|");
								}
							}
						}
					}
					if (inRight.length() != 0) {
						listIterator.remove();
						listIterator.add(new Grammar(left.toString(), inRight
								.substring(0, inRight.length() - 1)));
					}
				}
			}
		}
	}

	private void removeLeftRecursion(Character left) {
		ListIterator listIterator = productions.listIterator();
		while (listIterator.hasNext()) {
			Grammar grammar = listIterator.next();
			if (grammar.getLeft().equals(left.toString())) {
				String[] rights = grammar.getRight().split("\\\\|");
				boolean isLeftRecursion = false;
				for (int i = 0; i < rights.length; i++) {
					if (rights[i].startsWith(left.toString())) {
						isLeftRecursion = true;
					}
				}
				if (isLeftRecursion) {
					listIterator.remove();
					String oneRight = "", twoRight = "";
					for (int i = 0; i < rights.length; i++) {
						if (!rights[i].startsWith(left.toString())) {
							oneRight += (rights[i]
									.concat(left.toString() + "‘") + "|");
						} else {
							twoRight += (rights[i].replaceFirst(
									left.toString(), "").concat(
									left.toString() + "‘") + "|");
						}
					}
					listIterator.add(new Grammar(left.toString(), oneRight
							.substring(0, oneRight.length() - 1)));
					listIterator.add(new Grammar(left.toString() + "‘",
							twoRight.concat("epsilon")));
				}
			}
		}
	}

	@Override
	public String toString() {
		String temp = "非终结符: ";
		for (int i = 0; i < nonTerminatingSymbol.size(); i++) {
			temp += nonTerminatingSymbol.get(i) + " ";
		}
		temp+="  共计:"+nonTerminatingSymbol.size();
		temp += "\\n终结符: ";
		for (int i = 0; i < terminatingSymbol.size(); i++) {
			temp += terminatingSymbol.get(i) + "  ";
		}
		temp+="  共计:"+terminatingSymbol.size();
		temp += "\\n消除左递归后的文法:\\n";
		for (int i = 0; i < productions.size(); i++) {
			temp += (productions.get(i) + "\\n");
		}
		return temp;
	}
}

package com.siwanghu.syntaxanalyzer.test;

import java.util.LinkedList;
import java.util.List;

import com.siwanghu.syntaxanalyzer.algorithm.Production;
import com.siwanghu.syntaxanalyzer.bean.Grammar;

public class Test {
	public static void main(String[] args) {
		System.out.println("The Productions of G");
		Grammar g1 = new Grammar("S", "Qc|c");
		Grammar g2 = new Grammar("Q", "Rb|b");
		Grammar g3 = new Grammar("R", "Sa|a");
		List g_productions = new LinkedList();
		g_productions.add(g3);
		g_productions.add(g2);
		g_productions.add(g1);
		Production g_production = new Production(g_productions);
		g_production.removeLeftRecursion();
		System.out.print(g_production);
		System.out.println("end G\\n");

		System.out.println("The Productions of H");
		Grammar h1 = new Grammar("E", "E+T|T");
		Grammar h2 = new Grammar("T", "T*F|F");
		Grammar h3 = new Grammar("F", "(E)|i");
		List h_productions = new LinkedList();
		h_productions.add(h1);
		h_productions.add(h2);
		h_productions.add(h3);
		Production h_production = new Production(h_productions);
		h_production.removeLeftRecursion();
		System.out.print(h_production);
		System.out.println("end H");

	}

}
时间: 2024-10-22 14:25:42

java实现消除文法的左递归的相关文章

消除文法左递归

1.直接消除左递归 假定P关于的全部产生式是 P->Pα1|Pα2|…|Pαm|β1|β2|…|βn (每个α都不等于ε,每个β都不以P开头) 方法:左递归变右递归 P->β1P'|β2P'|…|βnP' P'->α1P'|α2P'|…|αmP'|ε 例:给定文法G(S): E->E+T|T T->T*F|F F->(E)|i 消除其直接左递归G(E): E->TE' E'->+TE'|ε T->FT' T'->*FT'|ε F->(E)|

【转】消除左递归

转自:http://guanjy0129.blog.163.com/blog/static/111549445201061491810507/ 一个文法含有下列形式的产生式之一时: 1)A→Aβ,A∈VN,β∈V* 2)A→Bβ,B→Aα,A.B∈VN,α.β∈V* 则称该文法是左递归的. 然而,一个文法是左递归时,不能采取自顶向下分析法. 消除左递归方法有: a)把直接左递归改写为右递归: 设有文法产生式:A→Aβ|γ.其中β非空,γ不以A打头. 可写为:A→γA' A'→βA'|ε 一般情况

二义性 消除左递归

书是龙书 编译器中常用的方法可以分为自顶向下和自底向上的.一个是从语法分析树的顶部开始向底部构造语法分析树,一个则是从叶子节点开始,逐渐向根结点构造,这两种分析方法中,语法分析器的输入总是照着从左向右. 二义性:如果一个文法可以为某个句子生成多棵语法分析树,那么他就是二义性的. 例如例子id + id * id 消除左递归 如果一个文法中有一个非终结符号A使得对某个串a 存在一个推导A=>Aa 那么这个文法就是左递归 消除办法: A-> Aa1| Aa2|......Aam|β1|β2|βn

文法改进(消除左递归)

在上次的文法中有存在左递归的情况,将会影响以后的语法分析使用,所以需要消除左递归,以便于语法分析使用. <程序> → <外部声明> <程序>` <程序>`→<程序> | ε <外部声明> → <函数定义> | <定义> <函数定义> → <函数声明> <函数体> <函数声明> → <函数返回类型> <函数头> <函数返回类型>

消除文法左递归的算法

原理 存储文法的数据结构 1 typedef struct P{ 2 char key; // 产生式左部 3 char * value [16]; // 产生式右部 4 int count; // 几组规则 5 }P; 6 typedef struct G{ 7 char * vn ; // 非终结符集合 8 char * vt ; // 终结符集合 9 P p[16]; // 产生式 10 char start; // 开始符号 11 int pcount ; 12 }G; 文法G由多条产生

如何消除左递归

首先,什么叫做左递归呢? 一个左递归的语法通常有这样的形式 :  A-> Aa .而自顶向下的语法分析是无法处理左递归语法的.为什么呢?无论是递归分析还是预测分析或者是LL文法分析,在碰到左递归这种语法时都会陷入死循环当中.如果我们用递归分析,那么在分析A这个非终结符号的时候就会调用functionA,functionA将A分解成A,a,然后在我们再次碰到A的时候又会调用functionA,这样便形成了无限递归.如果我们用非递归的LL文法分析,那么在我们将把A->Aa无限次地压入到栈中,即每次

第十次——消除左递归

1.将以下文法消除左递归,求FIRST集.FOLLOW集,SELECT集,并分析符号串 i*i+i        E -> E+T | T      T -> T*F | F      F -> (E) | i 消除左递归: E→TE' E'→+TE'|ε T→FT' T'→*FT'|ε F→(E)|i FIRST集: FIRST(TE')={T} FIRST(+TE')={+} FIRST(ε)={ε} FIRST(FT')={F} FIRST(*FT')={*} FIRST((E))

10 消除左递归

1.将以下文法消除左递归,并分析符号串 i*i+i   (1)E -> E+T | T E -> TE' E' -> +TE'|ε (2)T -> T*F | F T -> FT' T' -> *F|ε (3)F -> (E) | i 2.P101练习7(2)(3)文法改写,并分别求FIRST集.FOLLOW集,和SELECT集 (2) A -> aABe|a B -> Bb|d First(A)={a,e} First(B)={b,d}  (3) S

编译原理:消除左递归

1.将以下文法消除左递归,分析符号串 i*i+i . 并分别求FIRST集.FOLLOW集,和SELECT集 E -> E+T | T T -> T*F | F F -> (E) | i 2.P101练习7(2)(3)文法改写,并分别求FIRST集.FOLLOW集,和SELECT集 课堂练习: 求以下文法的FIRST集.FOLLOW集和SELECT集. S->ApA->a |εA->cA A->aA S->ApS->BqA->aA->cAB