-
编译原理实验之删除无用符号和无用产生式 - [About Compiler Principle]
2009-11-07
删除无用符号和无用产生式——对某一文法产生式集中的无用符号和无用产生式进行删除,达到化简文法的目的。
import java.util.*;
public class RemoveUnuseful {
public static void main(String[] args){
Wenfa G=new Wenfa();
G.CreatGenerate();
System.out.println("原始文法如下:");
G.output();
System.out.println("删除无用符号和产生式之后结果:");
SuanFas.Suanfa1(G);
G.output();
}
}class SuanFas{
public static void Suanfa1(Wenfa G1){//删除无用符号和无用产生式
SuanFas.Suanfa11(G1);
SuanFas.Suanfa12(G1);
}
private static void Suanfa11(Wenfa G1){//删除无用符号和无用产生式Part1
String N="";
boolean isAdd=false;
for(int i=0;i<G1.pNum;i++){
if(!Belong(G1.p[i].left,N)&&(BelongS(G1.p[i].right,G1.T)||G1.p[i].right==null)){
N=N+G1.p[i].left;
}
}
do{
isAdd=false;
for(int i=0;i<G1.pNum;i++){
if(!Belong(G1.p[i].left,N)&&(BelongS2(G1.p[i].right,G1.T,N))){
N=N+G1.p[i].left;
isAdd=true;
}
}
}while(isAdd);
G1.N=N;
int renum=0;
for(int i=0;i<G1.pNum;i++){
if(Belong(G1.p[i].left,N)&&BelongS2(G1.p[i].right,N,G1.T)){
continue;
}else{
G1.p[i]=null;
renum++;
}
}
generate[] p=new generate[G1.pNum-renum];
int j=0;
for(int i=0;i<G1.pNum;i++){
if(G1.p[i]!=null) {
p[j]=G1.p[i];
j++;
}
}G1.p=p;
G1.pNum=j;
}
private static void Suanfa12(Wenfa G1){//删除无用符号和无用产生式Part2
String N="";
String T="";
N=N+G1.start;
boolean isAdd=false;
do{
isAdd=false;
for(int i=0;i<G1.pNum;i++){
if(Belong(G1.p[i].left,N)){
for(int j=0;j<G1.p[i].right.length();j++){
if(!Belong(G1.p[i].right.charAt(j),T)&&Belong(G1.p[i].right.charAt(j),G1.T)){
T=T+G1.p[i].right.charAt(j);
isAdd=true;
}else if(!Belong(G1.p[i].right.charAt(j),N)&&Belong(G1.p[i].right.charAt(j),G1.N)){
N=N+G1.p[i].right.charAt(j);
isAdd=true;
}
}
}
}
}while(isAdd);
G1.N=N;
G1.T=T;
int renum=0;
for(int i=0;i<G1.pNum;i++){
if(!Belong(G1.p[i].left,N)) G1.p[i]=null;
else if(!BelongS2(G1.p[i].right,N,T)){
G1.p[i]=null;
renum++;
}
}
generate[] p=new generate[G1.pNum-renum];
int j=0;
for(int i=0;i<G1.pNum;i++){
if(G1.p[i]!=null){
p[j]=G1.p[i];
j++;
}
}G1.p=p;
G1.pNum=j;
}
private static boolean Belong(char a,String b){
for(int i=0;i<b.length();i++){
if(a==b.charAt(i))return true;
}
return false;
}
private static boolean BelongS(String a,String b){
int len=0;
for(int i=0;i<a.length();i++){
for(int j=0;j<b.length();j++){
if(a.charAt(i)==b.charAt(j)){
len++;
break;
}
}
}
if(a.length()==len) return true;
else return false;
}
private static boolean BelongS2(String a,String b,String c){
for(int i=0;i<b.length();i++){
for(int j=0;j<c.length();j++){
if(b.charAt(i)==c.charAt(j)){
System.out.println("Error!");
return false;
}
}
}
int len=0;
for(int i=0;i<a.length();i++){
for(int j=0;j<b.length();j++){
if(a.charAt(i)==b.charAt(j)){
len++;
break;
}
}
}
for(int i=0;i<a.length();i++){
for(int j=0;j<c.length();j++){
if(a.charAt(i)==c.charAt(j)){
len++;
break;
}
}
}
if(a.length()==len) return true;
else return false;
}
}class Wenfa{
public Wenfa(){
Scanner in=new Scanner(System.in);
System.out.print("请输入非终结符号集合(连续输入不需分隔):");
N=in.next();
System.out.print("请输入终结符号集合(连续输入不需分隔):");
T=in.next();
System.out.print("请输入起始符号:");
start=in.next().charAt(0);
System.out.print("请输入文法规则P的数量:");
pNum=in.nextInt();
System.out.println();
}
public void CreatGenerate(){
Scanner in=new Scanner(System.in);
p=new generate[pNum];
for(int i=0;i<pNum;i++){
p[i]=new generate();
}
for(int i=0;i<pNum;i++){
System.out.print("请输入第"+(i+1)+"个规则的左部:");
p[i].left=in.nextLine().charAt(0);
System.out.print("请输入第"+(i+1)+"个规则的右部:");
p[i].right=in.nextLine();
System.out.println();
}
in.close();
}
public void output(){
System.out.println("G=({"+N+"},{"+T+"},P,"+start+")");
System.out.print("P: ");
for(int i=0;i<pNum;i++){
if(p[i]!=null) System.out.print(p[i].left+"->"+p[i].right+" ");
}
System.out.print("\n");
}
char start;
String N;
String T;
int pNum;
generate[] p;
}class generate{
public char left;
public String right;
} -
编译原理实验之词法分析 - [About Compiler Principle]
2009-11-07
正在上编译原理这门课,一些编程实验的代码也就放上来吧。代码只反映大概思想,一些比如容错性等细节没时间做具体处理。程序我是这样写了但不敢说没有差错,仅供参考。
词法分析——对输入的一段C-程序代码,进行单词分析,构造Token序列,删除无用字符如空格,注释等。
import java.io.*;
public class WordAnalysis{
public static void main(String[] args) throws IOException{
FileReader read=new FileReader("code.txt");
BufferedReader reader=new BufferedReader(read);
String line=reader.readLine();//这行的字符串
int lineNum=1; //行号
int curStart=0; //词的开始位置
int now=0; //当前的序号
char current; //当前的字符
String str="";
Token curToken=new Token(0,"","",null);
Token head=curToken;
while(line!=null){//逐行分析
for(now=0;now<line.length();now++){//当前行分析
current=line.charAt(now);
//判断数字
if(isNum(current)){
while(isNum(current)){
now++;
if(now>=line.length()) break;
if(!isNum(line.charAt(now))&&line.charAt(now)!=' '
&&!isSpcial(line.charAt(now))){
System.out.println("Error: 非标准数字类型单词!(Line:"+lineNum+")");
return;
}
current=line.charAt(now);
}
str=line.substring(curStart,now);
curToken.nextToken=new Token(lineNum,str,"NUM",null);
curToken=curToken.nextToken;
}
//判断字符
if(isChar(current)){
while(isChar(current)){
now++;
if(now>=line.length()) break;
if(!isChar(line.charAt(now))&&line.charAt(now)!=' '
&&!isSpcial(line.charAt(now))){
System.out.println("Error: 非标准字符类型单词!");
return;
}
current=line.charAt(now);
}
str=line.substring(curStart,now);
if(str.equals("else")){
curToken.nextToken=new Token(lineNum,str,"ELSE",null);
curToken=curToken.nextToken;
}
else if(str.equals("if")){
curToken.nextToken=new Token(lineNum,str,"IF",null);
curToken=curToken.nextToken;
}
else if(str.equals("int")){
curToken.nextToken=new Token(lineNum,str,"INT",null);
curToken=curToken.nextToken;
}
else if(str.equals("return")){
curToken.nextToken=new Token(lineNum,str,"RETURN",null);
curToken=curToken.nextToken;
}
else if(str.equals("while")){
curToken.nextToken=new Token(lineNum,str,"WHILE",null);
curToken=curToken.nextToken;
}
else if(str.equals("void")){
curToken.nextToken=new Token(lineNum,str,"VOID",null);
curToken=curToken.nextToken;
}
else{
curToken.nextToken=new Token(lineNum,str,"ID",null);
curToken=curToken.nextToken;
}
curStart=now+1;
}
//判断标点
if(current==';'){
str=";";
curToken.nextToken=new Token(lineNum,str,"PUNCTUATION",null);
curToken=curToken.nextToken;
curStart=now+1;
}
else if(current==','){
str=",";
curToken.nextToken=new Token(lineNum,str,"PUNCTUATION",null);
curToken=curToken.nextToken;
curStart=now+1;
}
//判断空格
else if(current==' '){
curStart=now+1;
}
//判断+-号
else if(current=='+'){
str="+";
curToken.nextToken=new Token(lineNum,str,"OPERATOR",null);
curToken=curToken.nextToken;
curStart=now+1;
}
else if(current=='-'){
str="-";
curToken.nextToken=new Token(lineNum,str,"OPERATOR",null);
curToken=curToken.nextToken;
curStart=now+1;
}
//判断({[号
else if(current=='('){
str="(";
curToken.nextToken=new Token(lineNum,str,"LPAREN",null);
curToken=curToken.nextToken;
curStart=now+1;
}
else if(current=='['){
str="[";
curToken.nextToken=new Token(lineNum,str,"LPAREN",null);
curToken=curToken.nextToken;
curStart=now+1;
}
else if(current=='{'){
str="{";
curToken.nextToken=new Token(lineNum,str,"LPAREN",null);
curToken=curToken.nextToken;
curStart=now+1;
}
else if(current==')'){
str=")";
curToken.nextToken=new Token(lineNum,str,"RPAREN",null);
curToken=curToken.nextToken;
curStart=now+1;
}
else if(current==']'){
str="]";
curToken.nextToken=new Token(lineNum,str,"RPAREN",null);
curToken=curToken.nextToken;
curStart=now+1;
}
else if(current=='}'){
str="}";
curToken.nextToken=new Token(lineNum,str,"RPAREN",null);
curToken=curToken.nextToken;
curStart=now+1;
}
//判断<>=号
else if(current=='='){
if(line.charAt(now+1)=='='&&now<line.length()){
now++;
str="==";
curToken.nextToken=new Token(lineNum,str,"COMPARE",null);
curToken=curToken.nextToken;
curStart=now+1;
}else{
str="=";
curToken.nextToken=new Token(lineNum,str,"ASSIGNMENT",null);
curToken=curToken.nextToken;
curStart=now+1;
}
}
else if(current=='>'){
if(line.charAt(now+1)=='='&&now<line.length()){
now++;
str=">=";
curToken.nextToken=new Token(lineNum,str,"COMPARE",null);
curToken=curToken.nextToken;
curStart=now+1;
}else{
str=">";
curToken.nextToken=new Token(lineNum,str,"COMPARE",null);
curToken=curToken.nextToken;
curStart=now+1;
}
}
else if(current=='<'){
if(line.charAt(now+1)=='='&&now<line.length()){
now++;
str="<=";
curToken.nextToken=new Token(lineNum,str,"COMPARE",null);
curToken=curToken.nextToken;
curStart=now+1;
}else{
str="<";
curToken.nextToken=new Token(lineNum,str,"COMPARE",null);
curToken=curToken.nextToken;
curStart=now+1;
}
}
else if(current=='!'){
if(line.charAt(now+1)=='='&&now<line.length()){
now++;
str="!=";
curToken.nextToken=new Token(lineNum,str,"COMPARE",null);
curToken=curToken.nextToken;
curStart=now+1;
}else{
System.out.println("Error:!");
break;
}
}
//判断*/号
else if(current=='*'){
if(line.charAt(now+1)=='/'&&now<line.length()){
System.out.println("Error:*/");
break;
}else{
str="*";
curToken.nextToken=new Token(lineNum,str,"OPERATOR",null);
curToken=curToken.nextToken;
curStart=now+1;
}
}
else if(current=='/'){
cango:
if(line.charAt(now+1)=='*'&&now<line.length()){
now=now+2;
while(line!=null){
while(now<line.length()){
if(line.charAt(now)=='*'&&line.charAt(now+1)=='/'){
now=now+1;
break cango;
}else{
now++;
}
}
line=reader.readLine();
lineNum++;
now=0;
}
System.out.println("Error:/*");
break;
}else{
str="/";
curToken.nextToken=new Token(lineNum,str,"OPERATOR",null);
curToken=curToken.nextToken;
curStart=now+1;
}
}
}//当前行分析结束
line=reader.readLine();
lineNum++;
curStart=0;
}
//结束处理
curToken.nextToken=new Token(-1,"end","END",null);
curToken=curToken.nextToken;
Token all=head.nextToken;
while(all!=null){
all.outprint();
all=all.nextToken;
System.out.println();
}
read.close();
reader.close();
}public static boolean isNum(char x){
if(x>='0'&&x<='9') return true;
else return false;
}
public static boolean isChar(char x){
if(x>='A'&&x<='Z'||x>='a'&&x<='z') return true;
else return false;
}
public static boolean isSpcial(char x){
char[] spe={'+','-','*','/','<','>','=','!',';',',','(',')','[',']','{','}'};
for(int i=0;i<spe.length;i++){
if(x==spe[i]) return true;
}
return false;
}
}class Token {
public Token(int lineNum,String word,String types,Token nextToken){
this.lineNum=lineNum;
this.word=word;
this.types=types;
this.nextToken=nextToken;
}
public void outprint(){
System.out.print("{"+lineNum+","+word+","+types+"} ");
}
public Token nextToken;
private int lineNum;
private String word;
private String types;
} -
NullPointerException - [About Java]
2009-09-26
NullPointerException,为什么报这种错误,这种报错肯定是java代码的错。
[ 所谓空指针异常,是因为用空(null)去调用属性或方法。
null表示没有这个对象,既然没有这个对象,那么去调用他的属性和方法,就会报异常。
<--主要有以下几种原因:
1、使用了未初始化的变量(虽然已经声明)
2、使用了未初始化的对象(虽然已经声明)
3、使用了关键字或已存在的类名作变量对象方法或类名。当应用程序试图在需要对象的地方使用 null 时,抛出该异常。
<--这种情况包括:
调用 null对象的实例方法。
访问或修改null对象的字段。
将null作为一个数组,获得其长度。
将null作为一个数组,访问或修改其时间片。
将null作为Throwable值抛出。]







