定义一个语法分析接口
public interface GrammarHandler {
char NULL_WORD_CHAR = '☯';
String NULL_WORD_STR = "☯";
/**
* 添加文法规则
* @param k 非终结符
* @param s 规则
*/
void addGrammar(char k, String s);
/**
* 输入语句验证是否符合文法规则
* @param s 被验证语句
* @return 成功返回true
*/
boolean isMatch(String s);
/**
* 添加文法完毕后初始化才可验证语句
* @param firstK 启始非终结符
*/
void init(char firstK);
}
定义LL1语法分析实现类
import org.apache.commons.lang.StringUtils;
import java.util.*;
/**
* @auther Buynow Zhao
* @create 2017/11/12
*/
public class LL1Handler implements GrammarHandler{
private Map<Character, Set<String>> grammarMap = new HashMap<Character, Set<String>>();
private Map<Character, Map<Character,String>> selectMap = new HashMap<Character, Map<Character,String>>();
private boolean isInit = false;
private Character firstK = null;
@Override
public void addGrammar(char k, String s) {
if (!grammarMap.containsKey(k)) {
grammarMap.put(k, new HashSet<String>());
}
grammarMap.get(k).add(s);
}
@Override
public boolean isMatch(String s) {
Stack<Character> gStack = new Stack<Character>();
Stack<Character> sStack = new Stack<Character>();
gStack.push('#');
sStack.push('#');
gStack.push(firstK);
for (int i=s.length()-1;i>=0;i--) {
sStack.push(s.charAt(i));
}
String s1 = null;
while (!(gStack.isEmpty()||sStack.isEmpty())) {
while (!(gStack.isEmpty() || sStack.isEmpty())
&& gStack.peek() == sStack.peek()) {
gStack.pop();
sStack.pop();
}
if (gStack.isEmpty() || sStack.isEmpty()) {
break;
}
s1 = null;
if (selectMap.get(gStack.peek()) != null) {
s1 = selectMap.get(gStack.pop()).get(sStack.peek());
}
if (s1 == null) {
return false;
}
if (GrammarHandler.NULL_WORD_STR.equals(s1)) {
continue;
}
for (int i=s1.length()-1;i>=0;i--) {
gStack.push(s1.charAt(i));
}
}
if (sStack.isEmpty()&&gStack.isEmpty()){
return true;
}
return false;
}
@Override
public void init(char firstK) {
if (this.isInit) {
return;
}
this.firstK = firstK;
getSelectMap();
this.isInit = true;
}
private void getSelectMap() {
for (Character k : grammarMap.keySet()) {
select(k);
}
}
private void select(char k) {
if (selectMap.containsKey(k)) {
return;
}
selectMap.put(k, new HashMap<Character,String>());
for (String s : grammarMap.get(k)) {
if (StringUtils.isEmpty(s)) {
follow(k);
}else{
selectMap.get(k).put(s.charAt(0),s);
}
}
}
private void follow(char k) {
char[] charArr = null;
for (Character k1 : grammarMap.keySet()) {
for (String s : grammarMap.get(k1)) {
charArr = s.toCharArray();
for (int i=0;i<charArr.length;i++) {
if (charArr[i] == k) {
if (i == charArr.length - 1) {
selectMap.get(k).put('#',GrammarHandler.NULL_WORD_STR);
}else{
select(charArr[i+1]);
for (Character c : selectMap.get(charArr[i + 1]).keySet()) {
selectMap.get(k).put(c,GrammarHandler.NULL_WORD_STR);
}
}
}
}
}
}
}
public static void main(String[] args) {
GrammarHandler handler = new LL1Handler();
handler.addGrammar('S',"dABA");
handler.addGrammar('A',"");
handler.addGrammar('A',"a");
handler.addGrammar('B',"bb");
handler.init('S');
String[] sArr = new String[]{"dbb","dab","dabba"};
for (String s : sArr) {
boolean result = handler.isMatch(s);
System.out.println(s+":"+result);
}
}
}
运行演示
- 测试的文法规则
- 添加规则到GrammarHandler
- handler.addGrammar(‘S’,”dABA”);
- handler.addGrammar(‘A’,”“);//A->NULL
- handler.addGrammar(‘A’,”a”);//A->a
- handler.addGrammar(‘B’,”bb”);//B->bb
- 被测试的句子
- String[] sArr = new String[]{“dbb”,”dab”,”dabba”};
- 循环遍历数组中的句子验证是否符合
for (String s : sArr) {
boolean result = handler.isMatch(s);
System.out.println(s+":"+result);
}
- 测试结果
