刚刚学习编译原理,这是第二章的代码的改写,源码
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>