import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
import java.util.Stack;
public class complies {
public static void main(String[] args) throws Exception {
getFF ff = getFF.getinstanceFF();
ff.readTxt();
ff.getFirst();
ff.getFollow();
ff.getSelect();
ff.test();
}
}
class getFF{
private static final getFF FF = new getFF();
private HashMap<Character,Nonterminal> nonterminals = new HashMap<>();
private ArrayList<String> grammars = new ArrayList<>();
private Character first = null;//文法开始符
//单例模式
private getFF(){}
public static getFF getinstanceFF(){
return FF;
}
//初始化各个非终结符的实例
public void readTxt() throws IOException {
File file = new File("grammar.txt");
BufferedReader br = new BufferedReader(new FileReader(file));
System.out.println();
System.out.println("===定义的文法是(可在grammar.txt文件中按下述格式输入文法):===");
System.out.println("===这里#符号代表空,&符号代表结束符,大写字母代表非终结符,->代表箭头,其余符号代表终结符===");
String str = null;
while((str = br.readLine())!=null){
if(str.length()==0){//防止空行出现
continue;
}
grammars.add(str);
System.out.println(str);
}
System.out.println();
first = grammars.get(0).charAt(0);
for(String line : grammars){//初始化非终结符各个实例
if(!nonterminals.containsKey(line.charAt(0))){
nonterminals.put(line.charAt(0),new Nonterminal());
}
}
br.close();
}
//求First集并展示
public void getFirst() throws IOException{
for(String line : grammars){//完成第一次循环并判断该非终结符是否可为空
Nonterminal temp = nonterminals.get(line.charAt(0));
for(int i = 3;i < line.length();++i){
char c = line.charAt(i);
if(c == '#'){
temp.setIsnull(true);
}
else if((i==3||line.charAt(i-1)=='|')){
if((c < 'A'||c > 'Z')){
temp.addFirst(c);//加入终结符集合
}
else{
temp.addFirstnonterminals(c);//加入非终结符集合(即T->F,F的first要加入T的first)
}
}
}
}
for(String line : grammars){//加入非终结符集合(即T->FH,如果F可为空,则H的first要加入T的first)
Nonterminal temp = nonterminals.get(line.charAt(0));
for(int i = 3;i < line.length();++i){
if(i == 3 || line.charAt(i-1)=='|'){
while(i < line.length() && line.charAt(i) >= 'A' && line.charAt(i) <= 'Z'
&& nonterminals.get(line.charAt(i)).isIsnull()){
if(i==line.length()-1||(i+1<line.length()&& line.charAt(i+1)=='|')){
temp.addFirst('#');
temp.setIsnull(true);
}
if( i+1 < line.length() && line.charAt(i+1)>= 'A' && line.charAt(i+1) <= 'Z'){
temp.addFirstnonterminals(line.charAt(++i));
}
else{
++i;
}
}
}
}
}
boolean isChanged = true;
var keyset = nonterminals.keySet();
while(isChanged){
isChanged = false;
for(Character nonterminal : keyset){
Nonterminal temp = nonterminals.get(nonterminal);
var firstNonterminals = temp.getFirstNonterminals();
for(Character firstterminal : firstNonterminals){
int num = temp.getFirst().size();
temp.addFirst(nonterminals.get(firstterminal).getFirst());
if(!isChanged && num != temp.getFirst().size()){
isChanged = true;
}
}
}
}
for(Character nonterminal : keyset){//S->AB
if(nonterminals.get(nonterminal).isIsnull()){
nonterminals.get(nonterminal).addFirst('#');
}
}
System.out.println("======各个非终结符的First集======");
for(Character nonterminal : keyset){
System.out.print(nonterminal+":");
for(Character first : nonterminals.get(nonterminal).getFirst()){
System.out.print(first+" ");
}
System.out.println();
}
}
//求Follow集并展示
public void getFollow(){
nonterminals.get(grammars.get(0).charAt(0)).addFollow('$');//将$置入Follow(文法开始符号的follow集)
for(String line : grammars){
Character first = line.charAt(0);
for(int i = line.length() - 1;i >= 3;--i){
Character c = line.charAt(i);
if(c =='#'){
continue;
}
if(i>3 && line.charAt(i-1) >= 'A' && line.charAt(i-1) <= 'Z' ){//follow集加入终结符,并处理各个非终结符Follow集的包含关系
if((c<'A' || c>'Z') && c!='|'){
nonterminals.get(line.charAt(i-1)).addFollow(c);
}
else if(c >= 'A' && c <= 'Z' && !nonterminals.get(c).isIsnull()){//当为空时,后面的步骤会添加first集,因此这里不用重复添加
nonterminals.get(line.charAt(i-1)).addFollow(nonterminals.get(c).getFirst());
}
}
if(i == line.length()-1||(i+1<line.length() && line.charAt(i+1)=='|')){//处理各个非终结符Follow集的包含关系
if(c >= 'A' && c <= 'Z'){
nonterminals.get(c).addFollowNonterminals(first);
while(i >= 4 && line.charAt(i-1) >= 'A' && line.charAt(i-1) <= 'Z'
&& nonterminals.get(line.charAt(i)).isIsnull()){
nonterminals.get(line.charAt(i-1)).addFollow(nonterminals.get(line.charAt(i)).getFirst());//#符号稍后处理
nonterminals.get(line.charAt(--i)).addFollowNonterminals(first);
}
}
}
}
}
var keyset = nonterminals.keySet();
boolean isChanged = true;
while(isChanged){
isChanged = false;
for(Character nonterminal : keyset){
Nonterminal temp = nonterminals.get(nonterminal);
var followNonterminals = temp.getFollowNonterminals();
for(Character followNonterminal : followNonterminals){
int num = temp.getFollow().size();
temp.addFollow(nonterminals.get(followNonterminal).getFollow());
if(!isChanged && num != temp.getFollow().size()){
isChanged = true;
}
}
}
}
System.out.println();
System.out.println("======各个非终结符的Follow集======");
for(Character nonterminal : keyset){
System.out.print(nonterminal+":");
for(Character follow : nonterminals.get(nonterminal).getFollow()){
if(follow == '#'){
continue;
}
System.out.print(follow+" ");
}
System.out.println();
}
}
//求Select集并展示
public void getSelect(){
System.out.println();
System.out.println("=========Select集=========");
for(String line : grammars){
Character temp = line.charAt(0);
Nonterminal nonterminal = nonterminals.get(temp);
HashSet<Character> first = new HashSet<>();
String nowLine = temp.toString() + "->";
for(int i = 3;i<= line.length();++i){
if(i==line.length()){
nonterminal.addGrammar(first, nowLine);
nowLine = temp.toString() + "->";
first= new HashSet<>();
continue;
}
if(line.charAt(i) == '|'){
nonterminal.addGrammar(first, nowLine);
nowLine = temp.toString() + "->";
first= new HashSet<>();
continue;
}
else{
nowLine += line.charAt(i);
}
}
}
//求各个产生式的first集合
Set<Character> keySet = nonterminals.keySet();
for(char key : keySet){
Nonterminal temp = nonterminals.get(key);
Set<String> keySet2 = temp.getGrammar().keySet();
for(String key2 : keySet2){
HashSet<Character> hashSet = temp.getGrammar().get(key2);
Character c = key2.charAt(3);
if(c == '#'){
hashSet.addAll(temp.getFollow());
}
else if(c < 'A' || c > 'Z'){
hashSet.add(c);
}
else{
hashSet.addAll(nonterminals.get(c).getFirst());
for(int i=4;i < key2.length();++i){
if(nonterminals.get(key2.charAt(i-1)).isIsnull()){
hashSet.addAll(nonterminals.get(key2.charAt(i)).getFirst());
if(i==key2.length()-1&&nonterminals.get(key2.charAt(i)).isIsnull()){
hashSet.addAll(temp.getFollow());
}
}
}
}
}
}
//打印select集
for(Character key :keySet){
Nonterminal temp = nonterminals.get(key);
Set<String> keySet2 = temp.getGrammar().keySet();
for(String key2:keySet2){
System.out.print("select("+key2+") = {");
HashSet<Character> hashSet = temp.getGrammar().get(key2);
for(Character c : hashSet){
if(c == '#'){
continue;
}
System.out.print(c+" ");
}
System.out.println("}");
}
}
System.out.println();
}
public void test(){
String input = "i+i*i$";
Queue<Character>que = new LinkedList<>();
for(Character i :input.toCharArray()){
que.offer(i);
}
Stack<Character>sta2 = new Stack<>();//栈
sta2.push('$');
sta2.push(first);
while(sta2.size() > 1){
Character c1 = sta2.pop();
Character c2 = que.peek();
if(c1>='A'&&c1<='Z'){
Nonterminal temp = nonterminals.get(c1);
HashMap<String,HashSet<Character>> tempGrammars = temp.getGrammar();
Set<String> keySet = tempGrammars.keySet();
boolean found = false;
for(String key : keySet){
if(tempGrammars.get(key).contains(c2)){
found = true;
for(int i = key.length()-1;i>=3;--i){
if(key.charAt(i)=='#'){
break;
}
sta2.push(key.charAt(i));
}
break;
}
}
if(!found){
System.out.println(input + " 判断失败");
return;
}
}
else if(c2 == '$'){
if(c1<'A'||c1>'Z'){
System.out.println(input + " 判断失败");
return;
}
else{
if(!nonterminals.get(c1).isIsnull()){
System.out.println(input + " 判断失败");
return;
}
}
}
else{
if(c1!=c2){
System.out.println(input + " 判断失败");
return;
}
else {
que.poll();
}
}
}
System.out.println(input+" 判断成功");
}
}
class Nonterminal{
private boolean isnull = false;
private HashSet<Character>firstNonterminals = new HashSet<>();
private HashSet<Character>followNonterminals = new HashSet<>();
private HashSet<Character>First = new HashSet<>();
private HashSet<Character>Follow = new HashSet<>();
private HashMap<String,HashSet<Character>>grammar = new HashMap<>();
public HashMap<String,HashSet<Character>> getGrammar() {
return grammar;
}
public void addGrammar(HashSet<Character>set, String grammar) {
this.grammar.put(grammar,set);
}
public boolean isIsnull() {
return isnull;
}
public void setIsnull(boolean isnull) {
this.isnull = isnull;
}
public HashSet<Character> getFirstNonterminals() {
return firstNonterminals;
}
public void addFirstnonterminals(Character firstnonterminal) {
firstNonterminals.add(firstnonterminal);
}
public HashSet<Character> getFollowNonterminals() {
return followNonterminals;
}
public void addFollowNonterminals(Character followNonterminal) {
followNonterminals.add(followNonterminal);
}
public HashSet<Character> getFirst() {
return First;
}
public void addFirst(Character first) {
First.add(first);
}
public void addFirst(HashSet<Character>First) {
this.First.addAll(First);
}
public HashSet<Character> getFollow() {
return Follow;
}
public void addFollow(Character follow) {
Follow.add(follow);
}
public void addFollow(HashSet<Character>Follow) {
this.Follow.addAll(Follow);
}
}
LL(1)文法java代码
最新推荐文章于 2024-07-14 22:18:32 发布