HelloWorld 善战者,求之于势,不责于人;故能择人而任势。

知止而后有定,定而后能静,静而后能安,安而后能虑,虑而后能得。物有本末,事有终始。知所先后,则近道矣。

  BlogJava :: 首页 ::  :: 联系 ::  :: 管理 ::
  167 随笔 :: 1 文章 :: 40 评论 :: 0 Trackbacks
刚刚学习编译原理,这是第二章的代码的改写,源码
http://www.blogjava.net/Files/zhaochengming/compiler%20section%202%20parse.rar

1.KeyWord.java 关键字对象类
package parse;

public class KeyWord {
    
private String lexptr;
    
private int token;
    
public KeyWord(String lexptr, int token) {
        
this.lexptr = lexptr;
        
this.token = token;
    }

    
public String getLexptr() {
        
return lexptr;
    }

    
public void setLexptr(String lexptr) {
        
this.lexptr = lexptr;
    }

    
public int getToken() {
        
return token;
    }

    
public void setToken(int token) {
        
this.token = token;
    }

}

2.SymTable.java 符号表对象类
package parse;

import java.util.ArrayList;
import java.util.List;

/**
 * 符号表
 * 
@author Administrator
 *
 
*/

public class SymTable {
    
private static List<KeyWord> SYMTABLE = new ArrayList<KeyWord>();
    
// 符号表最大容量
    private static final int SYMMAX = 999;
    
// 字符串最大长度
    public static final int STRMAX = 100;
    
private static final KeyWord KEYWORDS[] = {
        
new KeyWord(null,0),
        
new KeyWord("DIV", Token.DIV),
        
new KeyWord("ADD", Token.ADD),
        
new KeyWord("SUB", Token.SUB),
        
new KeyWord("MOD", Token.MOD),
        
new KeyWord("MUL", Token.MUL),
    }
;
    
    
// 初始化symtable
    static {
        
for(KeyWord keyword : KEYWORDS) {
            insert(keyword.getLexptr(), keyword.getToken());
        }

    }

    
    
/**
     * 在符号表中插入新的符号
     * 
@param lexptr
     * 
@param token
     * 
@return
     
*/

    
public static int insert(String lexptr, int token) {
        
int lexptrlen = 0;
        
if(lexptr != null) lexptrlen = lexptr.length();
        
if(SYMTABLE.size() >= SYMMAX) {
            
throw new IllegalStateException("符号表满。");
        }

        
if(lexptrlen >= STRMAX) {
            
throw new IllegalStateException("lexptr超过最大长度。");
        }

        SYMTABLE.add(
new KeyWord(lexptr, token));
        
return SYMTABLE.size() - 1;
    }

    
    
/**
     * 返回lexptr在符号表中的下标
     * 
@param lexptr
     * 
@return
     
*/

    
public static int lookup(String lexptr) {
        
for (int i = 1; i < SYMTABLE.size(); i++{
            
if(SYMTABLE.get(i).getLexptr().equals(lexptr)) {
                
return i;
            }

        }

        
return 0;
    }

    
    
public static KeyWord getKeyWord(int index) {
        
return SYMTABLE.get(index);
    }

    
}


3.Lex.java 词法分析对象类
package parse;


public class Lex {
    
private int last = -1;
    
private int pos = 0;            // 当前位置
    private ParseReader pr;
    
private String buf;
    
private int tokenVal;
    
private Parser parser;
    
    
public Lex(ParseReader pr, Parser parse) {
        
this.pr = pr;
        
this.parser = parse;
    }

    
    
public int lexan() {
        
int t;
        
while (true{
            t 
= getChar();
            
if(t == ' ' || t == '\r');
            
else if(isDigit(t)) {
                tokenVal 
= 0;
                
while(isDigit(t)) {
                    tokenVal 
= tokenVal* 10 + (t - '0');
                    t 
= getChar();
                }

                ungetc(t);
                
return Token.NUM;
            }
 else if (isAlpha(t)) {
                
int p = -1, b = 0;
                StringBuilder sb 
= new StringBuilder();
                
while (isDigit(t) || isAlpha(t)) {
                    sb.append((
char)t);
                    t 
= getChar();
                    b
++;
                }

                
if(b >= SymTable.STRMAX) {
                    parser.error(
"词法分析错误");
                }

                
if(t != Token.EOF) {
                    ungetc(t);
                }

                p 
= SymTable.lookup(sb.toString());
                
if(p == 0{
                    p 
= SymTable.insert(sb.toString(), Token.ID);
                }

                tokenVal 
= p;
                
return SymTable.getKeyWord(tokenVal).getToken();
                
            }
 else if (t == Token.EOF) {
                
return Token.DONE;
            }
 else {
                tokenVal 
= Token.NULL;
                
return t;
            }

        }

    }

    
    
public int getTokenVal() {
        
return tokenVal;
    }

    
    
public int getChar() {
        
if(last < 0{
            
if(buf != null && pos < buf.length()) {
                
return buf.charAt(pos++);
            }
 else {
                
if(pr.isEof()) {
                    
return Token.EOF;
                }
 else {
                    buf 
= pr.readLine();
                    pos 
= 0;
                    
return getChar();
                }

            }

        }
 else {
            
int c = last;
            last 
= -1;
            
return c;
        }

    }

    
    
public void ungetc(int c) {
        last 
= c;
    }

    
    
public boolean isDigit(int t) {
        
return t >= '0' && t <= '9';
    }
    
    
public boolean isAlpha (int t) {
        
return ((t >= 'A' && t <= 'Z'|| (t >= 'a' && t <= 'z'));
    }
    
    
    
public int getLineNo() {
        
return pr.getLineNo();
    }

    
    
public int getPos() {
        
return pos;
    }

    
    
    
}


4.Parser.java 语法分析对象类
package parse;

import java.io.FileNotFoundException;

public class Parser {
    
private StringBuilder temp = new StringBuilder();
    
private Lex lex;
    
int lookahead;

    
public Parser(ParseReader pr) {
        lex 
= new Lex(pr,this);
    }

    
    
public void parse() {
        lookahead 
= lex.lexan();
        
while (lookahead != Token.DONE) {
            expr(); match(
';');
        }

        out(
"后缀表达式为: "+temp.toString());
    }

    
    
private void expr() {
        
int t;
        term();
        
while(true{
            
switch(lookahead) {
            
case '+':
            
case '-':
            
case Token.ADD:
            
case Token.SUB:
                t 
= lookahead;
                match(lookahead); term(); emit(t, Token.NULL);
                
continue;
            
default:
                
return;
            }

        }

    }

    
    
private void term() {
        
int t;
        factor();
        
while(true){
            
switch(lookahead) {
            
case '*':
            
case '/':
            
case '%':
            
case Token.MOD:
            
case Token.DIV:
            
case Token.MUL:
                t 
= lookahead;
                match(lookahead); factor(); emit(t, Token.NULL);
                
continue;
            
default:
                
return;
            }

        }

    }

    
    
private void factor() {
        
switch(lookahead) {
        
case '(':
            match(
'('); expr(); match(')'); break;
        
case Token.NUM:
            emit(Token.NUM, lex.getTokenVal()); match(Token.NUM); 
break;
        
case Token.ID:
            emit(Token.ID, lex.getTokenVal()); match(Token.ID); 
break;
        
default:
            error(
"语法分析错误");
        }

    }

    
    
private void match(int t) {
        
if(lookahead == t) {
            lookahead 
= lex.lexan();
        }
 else error("语法错误");
    }


    
    
public void emit(int t, int token) {
        
switch(t) {
        
case '+':
        
case '-':
        
case '*':
        
case '%':
        
case '/':
            temp.append(
" ").append((char)t).append(" ");
            out(String.valueOf((
char)t));break;
        
case Token.DIV:
            temp.append(
" DIV ");
            out(
"DIV");break;
        
case Token.MOD:
            temp.append(
" MOD ");
            out(
"MOD");break;
        
case Token.MUL:
            temp.append(
" MUL ");
            out(
"MUL");break;
        
case Token.ADD:
            temp.append(
" ADD ");
            out(
"ADD");break;
        
case Token.SUB:
            temp.append(
" SUB ");
            out(
" SUB ");break;
        
case Token.ID:
            temp.append(SymTable.getKeyWord(token).getLexptr());
            out(SymTable.getKeyWord(token).getLexptr());
            
break;
        
default:
            temp.append(
" ").append(token).append(" ");
            out(
"token " + Token.name(t) + ", tokenval "+token);
        }

    }


    
public void out(String msg) {
        System.out.println(msg);
    }

    
    
public static void main(String args[]) {
        Parser pr;
        
try {
            pr 
= new Parser(new ParseReaderRAF("c:/a.txt"));
            pr.parse();
            
        }
 catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }

    
    
public void error(String msg) {
        System.err.println(
"ERROR:[" + msg + "] LineNumber : " + lex.getLineNo() +", position :" + lex.getPos());
        System.exit(
0);
    }

}


5.ParseReader 词法分析读字符流接口
package parse;

public interface ParseReader {
    
public String readLine();
    
public boolean isEof();
    
public int getLineNo();
}

6.ParseReaderRAF 词法分析读字符流RandomAccessFile对象
package parse;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

public class ParseReaderRAF implements ParseReader{
    
private RandomAccessFile raf;
    
private int lineno = 0;
    
private String buf;
    
public ParseReaderRAF(String filepath) throws FileNotFoundException {
        
this.raf = new RandomAccessFile(new File(filepath), "r");
    }


    
public int getLineNo() {
        
return lineno;
    }


    
public boolean isEof() {
        
try {
            
if(raf.getFilePointer() >= raf.length())
                
return true;
        }
 catch (IOException e) {
            e.printStackTrace();
        }

        
return false;
    }


    
public String readLine() {
        
try {
            buf 
= raf.readLine();
            
//System.out.println(buf);
            lineno++;
        }
 catch (Exception e) {
            e.printStackTrace();
        }

        
return buf;
    }


}



</script>

posted on 2009-05-15 22:20 helloworld2008 阅读(603) 评论(0)  编辑  收藏 所属分类: 编译原理

只有注册用户登录后才能发表评论。


网站导航: