前几天做了语法分析器,,,最近才有时间发表出来
总共有四个包,12个类,
common包主要是公用的变量和公用类:
Enum(是枚举类型的类)
Error(表示错误的类)
Node(词法token节点)
Predict(predict集的数据结构)
SNLPredict(SNL的predict集)
production(产生式的数据结构)
SNLproduction(SNL的产生式集)
treeNode(语法树节点的数据结构)
lex包是用于词法分析的:
scanner(词法分析器)
main包就不解释了
parser包是用于语法分析的:
Parser(语法分析器)
drawTree(画树)
接下来就是代码了:
Enum.java
package common;
public interface Enum {
public enum lexType{
/* 簿记单词符号 */
ENDFILE, ERROR,
/* 保留字 */
PROGRAM, PROCEDURE, TYPE, VAR, IF,
THEN, ELSE, FI, WHILE, DO,
ENDWH, BEGIN, END, READ, WRITE,
ARRAY, OF, RECORD, RETURN,
INTEGER, CHAR,
/* 多字符单词符号 */
ID, INTC, CHARC,
/*特殊符号 */
ASSIGN, EQ, LT, PLUS, MINUS,
TIMES, OVER, LPAREN, RPAREN, DOT,
COLON, SEMI, COMMA, LMIDPAREN, RMIDPAREN,
UNDERANGE ;
}
/*非终极符*/
public enum nonTerminals{
Program, ProgramHead, ProgramName, DeclarePart, TypeDecpart,
TypeDec, TypeDecList, TypeDecMore, TypeId, TypeDef,
BaseType, StructureType, ArrayType, Low, Top,
RecType, FieldDecList, FieldDecMore, IdList, IdMore,
VarDecpart, VarDec, VarDecList, VarDecMore, VarIdList, VarIdMore,
ProcDecpart, ProcDec, ProcDecMore, ProcName, ParamList, ProcDeclaration ,
ParamDecList,ParamMore, Param, FormList, FidMore,
ProcDecPart, ProcBody, ProgramBody, StmList, StmMore, Stm,
AssCall, AssignmentRest,ConditionalStm, LoopStm, InputStm,
Invar, OutputStm, ReturnStm, CallStmRest, ActParamList,
ActParamMore,RelExp, OtherRelE, Exp, OtherTerm,
Term, OtherFactor, Factor, Variable, VariMore, FieldVar,
FieldVarMore,CmpOp, AddOp, MultOp ;
}
public enum nodeKind {
ProK , PheadK , TypeK , VarK , ProcDecK , StmLK , DecK , StmtK , ExpL ;
}
public enum decKind {
ArrayK , CharK , IntegerK , RecordK , IdK ;
}
public enum stmtKind {
IfK , WhileK , AssignK , ReadK , WriteK , CallK , ReturnK ;
}
public enum expKind {
OpK , ConstK , VariK ;
}
public enum varKind {
IdV , ArrayMembV , FieldMembV ;
}
public enum expType {
Void , Integer , Boolean ;
}
public enum paramType {
ValParamType , VarparamType ;
}
}
package common;
public class Error {
static int Line ;
static int Row;
static int ErrorType ;
static boolean Flag ;
public Error(){
Line = 0 ;
Row = 0 ;
ErrorType = 0 ;
Flag = false ;
}
public static void printError() {
if( ErrorType == 1 ) System.out.print( "词法错误" ) ;
else if( ErrorType == 2 ) System.out.print( "语法错误" ) ;
System.out.println( " 行:" + Line + " 列: " + Row ) ;
}
public static void setLine( int line ) {
Line = line ;
}
public static void setRow( int row ) {
Row = row ;
}
public static void setErrorType( int type ) {
ErrorType = type ;
}
public static void setFlag( boolean flag ) {
Flag = flag ;
}
public static int getLine() {
return Line ;
}
public static int getRow() {
return Row ;
}
public static int getErrorType() {
return ErrorType ;
}
public static boolean getFlag() {
return Flag ;
}
public static void setError( int line , int row , int type ) {
Line = line ;
Row = row ;
ErrorType = type ;
Flag = true ;
}
}
Node.java:
package common;
import common.Enum.*;
public class Node {
String Data ;
int Line , Row ;
lexType type ;
public Node(){
}
public String getData() {
return Data;
}
public void setData(String data) {
Data = data;
}
public int getLine() {
return Line;
}
public void setLine(int line) {
Line = line;
}
public int getRow() {
return Row;
}
public void setRow(int row) {
Row = row;
}
public lexType getType() {
return type;
}
public void setType(lexType integer) {
this.type = integer;
}
}
predict.java:
package common;
public class Predict {
int predictNum ;
Enum.lexType[] predict = new Enum.lexType[20] ;
public Predict() {
predictNum = 0 ;
}
public void setPredict( Enum.lexType pre ) {
predict[predictNum] = pre ;
predictNum ++ ;
}
public int getPredictNum() {
return predictNum ;
}
public Enum.lexType getPredict( int number ) {
return predict[number] ;
}
}
package common;
public class SNLpredict {
public Predict[] predict = new Predict[105] ;
public SNLpredict() {
for( int i = 0 ; i <= 104 ; i ++ )
predict[i] = new Predict() ;
predict[1].setPredict( Enum.lexType.PROGRAM ) ;
predict[2].setPredict( Enum.lexType.PROGRAM ) ;
predict[3].setPredict( Enum.lexType.ID ) ;
predict[4].setPredict( Enum.lexType.TYPE ) ; predict[4].setPredict( Enum.lexType.VAR ) ;
predict[4].setPredict( Enum.lexType.PROCEDURE ) ; predict[4].setPredict( Enum.lexType.BEGIN ) ;
predict[5].setPredict( Enum.lexType.VAR ) ; predict[5].setPredict( Enum.lexType.PROCEDURE ) ;
predict[5].setPredict( Enum.lexType.BEGIN ) ;
predict[6].setPredict( Enum.lexType.TYPE ) ;
predict[7].setPredict( Enum.lexType.TYPE ) ;
predict[8].setPredict( Enum.lexType.ID ) ;
predict[9].setPredict( Enum.lexType.VAR ) ; predict[9].setPredict( Enum.lexType.PROCEDURE ) ;
predict[9].setPredict( Enum.lexType.BEGIN ) ;
predict[10].setPredict( Enum.lexType.ID ) ;
predict[11].setPredict( Enum.lexType.ID ) ;
predict[12].setPredict( Enum.lexType.INTEGER ) ; predict[12].setPredict( Enum.lexType.CHAR ) ;
predict[13].setPredict( Enum.lexType.ARRAY ) ; predict[13].setPredict( Enum.lexType.RECORD ) ;
predict[14].setPredict( Enum.lexType.ID ) ;
predict[15].setPredict( Enum.lexType.INTEGER ) ;
predict[16].setPredict( Enum.lexType.CHAR ) ;
predict[17].setPredict( Enum.lexType.ARRAY ) ;
predict[18].setPredict( Enum.lexType.RECORD ) ;
predict[19].setPredict( Enum.lexType.ARRAY ) ;
predict[20].setPredict( Enum.lexType.INTC ) ;
predict[21].setPredict( Enum.lexType.INTC ) ;
predict[22].setPredict( Enum.lexType.RECORD ) ;
predict[23].setPredict( Enum.lexType.INTEGER ) ; predict[23].setPredict( Enum.lexType.CHAR ) ;
predict[24].setPredict( Enum.lexType.ARRAY ) ;
predict[25].setPredict( Enum.lexType.END ) ;
predict[26].setPredict( Enum.lexType.INTEGER ) ; predict[26].setPredict( Enum.lexType.CHAR ) ;
predict[26].setPredict( Enum.lexType.ARRAY ) ;
predict[27].setPredict( Enum.lexType.ID ) ;
predict[28].setPredict( Enum.lexType.SEMI ) ;
predict[29].setPredict( Enum.lexType.COMMA ) ;
predict[30].setPredict( Enum.lexType.PROCEDURE ) ; predict[30].setPredict( Enum.lexType.BEGIN ) ;
predict[31].setPredict( Enum.lexType.VAR ) ;
predict[32].setPredict( Enum.lexType.VAR ) ;
predict[33].setPredict( Enum.lexType.INTEGER ) ; predict[33].setPredict( Enum.lexType.CHAR ) ;
predict[33].setPredict( Enum.lexType.ARRAY ) ; predict[33].setPredict( Enum.lexType.RECORD ) ;
predict[33].setPredict( Enum.lexType.ID ) ;
predict[34].setPredict( Enum.lexType.PROCEDURE ) ; predict[34].setPredict( Enum.lexType.BEGIN ) ;
predict[35].setPredict( Enum.lexType.INTEGER ) ; predict[35].setPredict( Enum.lexType.CHAR ) ;
predict[35].setPredict( Enum.lexType.ARRAY ) ; predict[35].setPredict( Enum.lexType.RECORD ) ;
predict[35].setPredict( Enum.lexType.ID ) ;
predict[36].setPredict( Enum.lexType.ID ) ;
predict[37].setPredict( Enum.lexType.SEMI ) ;
predict[38].setPredict( Enum.lexType.COMMA ) ;
predict[39].setPredict( Enum.lexType.BEGIN ) ;
predict[40].setPredict( Enum.lexType.PROCEDURE ) ;
predict[41].setPredict( Enum.lexType.PROCEDURE ) ;
predict[42].setPredict( Enum.lexType.BEGIN ) ;
predict[43].setPredict( Enum.lexType.PROCEDURE ) ;
predict[44].setPredict( Enum.lexType.ID ) ;
predict[45].setPredict( Enum.lexType.RPAREN ) ;
predict[46].setPredict( Enum.lexType.INTEGER ) ; predict[46].setPredict( Enum.lexType.CHAR ) ;
predict[46].setPredict( Enum.lexType.ARRAY ) ; predict[46].setPredict( Enum.lexType.RECORD ) ;
predict[46].setPredict( Enum.lexType.ID ) ; predict[46].setPredict( Enum.lexType.VAR ) ;
predict[47].setPredict( Enum.lexType.INTEGER ) ; predict[47].setPredict( Enum.lexType.CHAR ) ;
predict[47].setPredict( Enum.lexType.ARRAY ) ; predict[47].setPredict( Enum.lexType.RECORD ) ;
predict[47].setPredict( Enum.lexType.ID ) ; predict[47].setPredict( Enum.lexType.VAR ) ;
predict[48].setPredict( Enum.lexType.RPAREN ) ;
predict[49].setPredict( Enum.lexType.SEMI ) ;
predict[50].setPredict( Enum.lexType.INTEGER ) ; predict[50].setPredict( Enum.lexType.CHAR ) ;
predict[50].setPredict( Enum.lexType.ARRAY ) ; predict[50].setPredict( Enum.lexType.RECORD ) ;
predict[50].setPredict( Enum.lexType.ID ) ;
predict[51].setPredict( Enum.lexType.VAR ) ;
predict[52].setPredict( Enum.lexType.ID ) ;
predict[53].setPredict( Enum.lexType.SEMI ) ; predict[53].setPredict( Enum.lexType.RPAREN ) ;
predict[54].setPredict( Enum.lexType.COMMA ) ;
predict[55].setPredict( Enum.lexType.TYPE ) ; predict[55].setPredict( Enum.lexType.VAR ) ;
predict[55].setPredict( Enum.lexType.PROCEDURE ) ; predict[55].setPredict( Enum.lexType.BEGIN ) ;
predict[56].setPredict( Enum.lexType.BEGIN ) ;
predict[57].setPredict( Enum.lexType.BEGIN ) ;
predict[58].setPredict( Enum.lexType.ID ) ; predict[58].setPredict( Enum.lexType.IF ) ;
predict[58].setPredict( Enum.lexType.WHILE ) ; predict[58].setPredict( Enum.lexType.RETURN ) ;
predict[58].setPredict( Enum.lexType.READ ) ; predict[58].setPredict( Enum.lexType.WRITE ) ;
predict[58].setPredict( Enum.lexType.END ) ; predict[58].setPredict( Enum.lexType.SEMI ) ;
predict[59].setPredict( Enum.lexType.ELSE ) ; predict[59].setPredict( Enum.lexType.FI ) ;
predict[59].setPredict( Enum.lexType.END ) ; predict[59].setPredict( Enum.lexType.ENDWH ) ;
predict[60].setPredict( Enum.lexType.SEMI ) ;
predict[61].setPredict( Enum.lexType.IF ) ;
predict[62].setPredict( Enum.lexType.WHILE ) ;
predict[63].setPredict( Enum.lexType.READ ) ;
predict[64].setPredict( Enum.lexType.WRITE ) ;
predict[65].setPredict( Enum.lexType.RETURN ) ;
predict[66].setPredict( Enum.lexType.ID ) ;
predict[67].setPredict( Enum.lexType.ASSIGN ) ; predict[67].setPredict( Enum.lexType.DOT ) ;
predict[67].setPredict( Enum.lexType.LMIDPAREN ) ;
predict[68].setPredict( Enum.lexType.LPAREN ) ;
predict[69].setPredict( Enum.lexType.LMIDPAREN ) ; predict[69].setPredict( Enum.lexType.DOT ) ;
predict[69].setPredict( Enum.lexType.ASSIGN ) ;
predict[70].setPredict( Enum.lexType.IF ) ;
predict[71].setPredict( Enum.lexType.WHILE ) ;
predict[72].setPredict( Enum.lexType.READ ) ;
predict[73].setPredict( Enum.lexType.ID ) ;
predict[74].setPredict( Enum.lexType.WRITE ) ;
predict[75].setPredict( Enum.lexType.RETURN ) ;
predict[76].setPredict( Enum.lexType.LPAREN ) ;
predict[77].setPredict( Enum.lexType.RPAREN ) ;
predict[78].setPredict( Enum.lexType.LPAREN ) ; predict[78].setPredict( Enum.lexType.INTC ) ;
predict[78].setPredict( Enum.lexType.ID ) ;
predict[79].setPredict( Enum.lexType.RPAREN ) ;
predict[80].setPredict( Enum.lexType.COMMA ) ;
predict[81].setPredict( Enum.lexType.LPAREN ) ; predict[81].setPredict( Enum.lexType.INTC ) ;
predict[81].setPredict( Enum.lexType.ID ) ;
predict[82].setPredict( Enum.lexType.LT ) ; predict[82].setPredict( Enum.lexType.EQ ) ;
predict[83].setPredict( Enum.lexType.LPAREN ) ; predict[83].setPredict( Enum.lexType.INTC ) ;
predict[83].setPredict( Enum.lexType.ID ) ;
predict[84].setPredict( Enum.lexType.LT ) ; predict[84].setPredict( Enum.lexType.EQ ) ;
predict[84].setPredict( Enum.lexType.RMIDPAREN ) ; predict[84].setPredict( Enum.lexType.THEN ) ;
predict[84].setPredict( Enum.lexType.ELSE ) ; predict[84].setPredict( Enum.lexType.FI ) ;
predict[84].setPredict( Enum.lexType.DO ) ; predict[84].setPredict( Enum.lexType.ENDWH ) ;
predict[84].setPredict( Enum.lexType.RPAREN ) ; predict[84].setPredict( Enum.lexType.END ) ;
predict[84].setPredict( Enum.lexType.SEMI ) ; predict[84].setPredict( Enum.lexType.COMMA ) ;
predict[85].setPredict( Enum.lexType.PLUS ) ; predict[85].setPredict( Enum.lexType.MINUS ) ;
predict[86].setPredict( Enum.lexType.LPAREN ) ; predict[86].setPredict( Enum.lexType.INTC ) ;
predict[86].setPredict( Enum.lexType.ID ) ;
predict[87].setPredict( Enum.lexType.PLUS ) ; predict[87].setPredict( Enum.lexType.MINUS ) ;
predict[87].setPredict( Enum.lexType.LT ) ; predict[87].setPredict( Enum.lexType.EQ ) ;
predict[87].setPredict( Enum.lexType.RMIDPAREN ) ; predict[87].setPredict( Enum.lexType.THEN ) ;
predict[87].setPredict( Enum.lexType.ELSE ) ; predict[87].setPredict( Enum.lexType.FI ) ;
predict[87].setPredict( Enum.lexType.DO ) ; predict[87].setPredict( Enum.lexType.ENDWH ) ;
predict[87].setPredict( Enum.lexType.RPAREN ) ; predict[87].setPredict( Enum.lexType.END ) ;
predict[87].setPredict( Enum.lexType.SEMI ) ; predict[87].setPredict( Enum.lexType.COMMA ) ;
predict[88].setPredict( Enum.lexType.TIMES ) ; predict[88].setPredict( Enum.lexType.OVER ) ;
predict[89].setPredict( Enum.lexType.LPAREN ) ;
predict[90].setPredict( Enum.lexType.INTC ) ;
predict[91].setPredict( Enum.lexType.ID ) ;
predict[92].setPredict( Enum.lexType.ID ) ;
predict[93].setPredict( Enum.lexType.ASSIGN ) ; predict[93].setPredict( Enum.lexType.TIMES ) ;
predict[93].setPredict( Enum.lexType.OVER ) ; predict[93].setPredict( Enum.lexType.PLUS ) ;
predict[93].setPredict( Enum.lexType.MINUS ) ; predict[93].setPredict( Enum.lexType.LT ) ;
predict[93].setPredict( Enum.lexType.EQ ) ; predict[93].setPredict( Enum.lexType.THEN ) ;
predict[93].setPredict( Enum.lexType.ELSE ) ; predict[93].setPredict( Enum.lexType.FI ) ;
predict[93].setPredict( Enum.lexType.DO ) ; predict[93].setPredict( Enum.lexType.ENDWH ) ;
predict[93].setPredict( Enum.lexType.RPAREN ) ; predict[93].setPredict( Enum.lexType.END ) ;
predict[93].setPredict( Enum.lexType.SEMI ) ; predict[93].setPredict( Enum.lexType.COMMA ) ;
predict[93].setPredict( Enum.lexType.RMIDPAREN ) ;
predict[94].setPredict( Enum.lexType.LMIDPAREN ) ;
predict[95].setPredict( Enum.lexType.DOT ) ;
predict[96].setPredict( Enum.lexType.ID ) ;
predict[97].setPredict( Enum.lexType.ASSIGN ) ; predict[97].setPredict( Enum.lexType.TIMES ) ;
predict[97].setPredict( Enum.lexType.OVER ) ; predict[97].setPredict( Enum.lexType.PLUS ) ;
predict[97].setPredict( Enum.lexType.MINUS ) ; predict[97].setPredict( Enum.lexType.LT ) ;
predict[97].setPredict( Enum.lexType.EQ ) ; predict[97].setPredict( Enum.lexType.THEN ) ;
predict[97].setPredict( Enum.lexType.ELSE ) ; predict[97].setPredict( Enum.lexType.FI ) ;
predict[97].setPredict( Enum.lexType.DO ) ; predict[97].setPredict( Enum.lexType.ENDWH ) ;
predict[97].setPredict( Enum.lexType.RPAREN ) ; predict[97].setPredict( Enum.lexType.END ) ;
predict[97].setPredict( Enum.lexType.SEMI ) ; predict[97].setPredict( Enum.lexType.COMMA ) ;
predict[97].setPredict( Enum.lexType.RMIDPAREN ) ;
predict[98].setPredict( Enum.lexType.LMIDPAREN ) ;
predict[99].setPredict( Enum.lexType.LT ) ;
predict[100].setPredict( Enum.lexType.EQ ) ;
predict[101].setPredict( Enum.lexType.PLUS ) ;
predict[102].setPredict( Enum.lexType.MINUS ) ;
predict[103].setPredict( Enum.lexType.TIMES ) ;
predict[104].setPredict( Enum.lexType.OVER ) ;
}
}
production.java:
package common;
public class Production {
Enum.nonTerminals Head ;
int productNum ;
class product {
public int flag ; // 0表示终极符,1表示非终极符
public Enum.nonTerminals nonterminals ;
public Enum.lexType terminals ;
}
product[] Product = new product[10] ;
public Production(){
productNum = 0 ;
}
public void setHead( Enum.nonTerminals head ) {
Head = head ;
}
public void setProduction( Enum.nonTerminals nonterminal ){
Product[productNum] = new product() ;
Product[productNum].flag = 1 ;
Product[productNum].nonterminals = nonterminal ;
productNum ++ ;
}
public void setProduction( Enum.lexType terminal ){
Product[productNum] = new product() ;
Product[productNum].flag = 0 ;
Product[productNum].terminals = terminal ;
productNum ++ ;
}
public Enum.nonTerminals getHead(){
return Head ;
}
public int getproductNum() {
return productNum ;
}
public int getflag( int number ) {
if( Product[number].flag == 1 ) return 1 ;
else return 0 ;
}
public Enum.nonTerminals getProductNonterminal( int number ) {
return Product[number].nonterminals ;
}
public Enum.lexType getProductTerminal( int number ) {
return Product[number].terminals ;
}
} ;
SNLProduction.java:
package common;
public class SNLproduct {
public Production[] product = new Production[105] ;
public SNLproduct() {
for( int i = 0 ; i <= 104 ; i ++ )
product[i] = new Production() ;
product[1].setHead( Enum.nonTerminals.Program ) ; product[1].setProduction( Enum.nonTerminals.ProgramHead ) ;
product[1].setProduction( Enum.nonTerminals.DeclarePart ) ; product[1].setProduction( Enum.nonTerminals.ProgramBody ) ;
product[2].setHead( Enum.nonTerminals.ProgramHead ) ; product[2].setProduction( Enum.lexType.PROGRAM ) ;
product[2].setProduction( Enum.nonTerminals.ProgramName ) ;
product[3].setHead( Enum.nonTerminals.ProgramName ) ; product[3].setProduction( Enum.lexType.ID ) ;
product[4].setHead( Enum.nonTerminals.DeclarePart ) ; product[4].setProduction( Enum.nonTerminals.TypeDecpart ) ;
product[4].setProduction( Enum.nonTerminals.VarDecpart ) ; product[4].setProduction( Enum.nonTerminals.ProcDecpart ) ;
product[5].setHead( Enum.nonTerminals.TypeDecpart ) ;
product[6].setHead( Enum.nonTerminals.TypeDecpart ) ; product[6].setProduction( Enum.nonTerminals.TypeDec ) ;
product[7].setHead( Enum.nonTerminals.TypeDec ) ; product[7].setProduction( Enum.lexType.TYPE ) ;
product[7].setProduction( Enum.nonTerminals.TypeDecList ) ;
product[8].setHead( Enum.nonTerminals.TypeDecList ) ; product[8].setProduction( Enum.nonTerminals.TypeId ) ;
product[8].setProduction( Enum.lexType.EQ ) ; product[8].setProduction( Enum.nonTerminals.TypeDef ) ;
product[8].setProduction( Enum.lexType.SEMI ) ; product[8].setProduction( Enum.nonTerminals.TypeDecMore ) ;
product[9].setHead( Enum.nonTerminals.TypeDecMore ) ;
product[10].setHead( Enum.nonTerminals.TypeDecMore ) ; product[10].setProduction( Enum.nonTerminals.TypeDecList ) ;
product[11].setHead( Enum.nonTerminals.TypeId ) ; product[11].setProduction( Enum.lexType.ID ) ;
product[12].setHead( Enum.nonTerminals.TypeDef ) ; product[12].setProduction( Enum.nonTerminals.BaseType ) ;
product[13].setHead( Enum.nonTerminals.TypeDef ) ; product[13].setProduction( Enum.nonTerminals.StructureType ) ;
product[14].setHead( Enum.nonTerminals.TypeDef ) ; product[14].setProduction( Enum.lexType.ID ) ;
product[15].setHead( Enum.nonTerminals.BaseType ) ; product[15].setProduction( Enum.lexType.INTEGER ) ;
product[16].setHead( Enum.nonTerminals.BaseType ) ; product[16].setProduction( Enum.lexType.CHAR ) ;
product[17].setHead( Enum.nonTerminals.StructureType ) ; product[17].setProduction( Enum.nonTerminals.ArrayType ) ;
product[18].setHead( Enum.nonTerminals.StructureType ) ; product[18].setProduction( Enum.nonTerminals.RecType ) ;
product[19].setHead( Enum.nonTerminals.ArrayType ) ; product[19].setProduction( Enum.lexType.ARRAY ) ;
product[19].setProduction( Enum.lexType.LMIDPAREN ) ; product[19].setProduction( Enum.nonTerminals.Low ) ;
product[19].setProduction( Enum.lexType.UNDERANGE ) ; product[19].setProduction( Enum.nonTerminals.Top ) ;
product[19].setProduction( Enum.lexType.RMIDPAREN ) ; product[19].setProduction( Enum.lexType.OF ) ;
product[19].setProduction( Enum.nonTerminals.BaseType ) ;
product[20].setHead( Enum.nonTerminals.Low ) ; product[20].setProduction( Enum.lexType.INTC ) ;
product[21].setHead( Enum.nonTerminals.Top ) ; product[21].setProduction( Enum.lexType.INTC ) ;
product[22].setHead( Enum.nonTerminals.RecType ) ; product[22].setProduction( Enum.lexType.RECORD ) ;
product[22].setProduction( Enum.nonTerminals.FieldDecList ) ; product[22].setProduction( Enum.lexType.END ) ;
product[23].setHead( Enum.nonTerminals.FieldDecList ) ; product[23].setProduction( Enum.nonTerminals.BaseType ) ;
product[23].setProduction( Enum.nonTerminals.IdList ) ; product[23].setProduction( Enum.lexType.SEMI ) ;
product[23].setProduction( Enum.nonTerminals.FieldDecMore ) ;
product[24].setHead( Enum.nonTerminals.FieldDecList ) ; product[24].setProduction( Enum.nonTerminals.ArrayType ) ;
product[24].setProduction( Enum.nonTerminals.IdList ) ; product[24].setProduction( Enum.lexType.SEMI ) ;
product[24].setProduction( Enum.nonTerminals.FieldDecMore ) ;
product[25].setHead( Enum.nonTerminals.FieldDecMore ) ;
product[26].setHead( Enum.nonTerminals.FieldDecMore ) ; product[26].setProduction( Enum.nonTerminals.FieldDecList ) ;
product[27].setHead( Enum.nonTerminals.IdList ) ; product[27].setProduction( Enum.lexType.ID ) ;
product[27].setProduction( Enum.nonTerminals.IdMore ) ;
product[28].setHead( Enum.nonTerminals.IdMore ) ;
product[29].setHead( Enum.nonTerminals.IdMore ) ; product[29].setProduction( Enum.lexType.COMMA ) ;
product[29].setProduction( Enum.nonTerminals.IdList ) ;
product[30].setHead( Enum.nonTerminals.VarDecpart ) ;
product[31].setHead( Enum.nonTerminals.VarDecpart ) ; product[31].setProduction( Enum.nonTerminals.VarDec ) ;
product[32].setHead( Enum.nonTerminals.VarDec ) ; product[32].setProduction( Enum.lexType.VAR ) ;
product[32].setProduction( Enum.nonTerminals.VarDecList ) ;
product[33].setHead( Enum.nonTerminals.VarDecList ) ; product[33].setProduction( Enum.nonTerminals.TypeDef ) ;
product[33].setProduction( Enum.nonTerminals.VarIdList ) ; product[33].setProduction( Enum.lexType.SEMI ) ;
product[33].setProduction( Enum.nonTerminals.VarDecMore ) ;
product[34].setHead( Enum.nonTerminals.VarDecMore ) ;
product[35].setHead( Enum.nonTerminals.VarDecMore ) ; product[35].setProduction( Enum.nonTerminals.VarDecList ) ;
product[36].setHead( Enum.nonTerminals.VarIdList ) ; product[36].setProduction( Enum.lexType.ID ) ;
product[36].setProduction( Enum.nonTerminals.VarIdMore ) ;
product[37].setHead( Enum.nonTerminals.VarIdMore ) ;
product[38].setHead( Enum.nonTerminals.VarIdMore ) ; product[38].setProduction( Enum.lexType.COMMA ) ;
product[38].setProduction( Enum.nonTerminals.VarIdList ) ;
product[39].setHead( Enum.nonTerminals.ProcDecpart ) ;
product[40].setHead( Enum.nonTerminals.ProcDecpart ) ; product[40].setProduction( Enum.nonTerminals.ProcDec ) ;
product[41].setHead( Enum.nonTerminals.ProcDec ) ; product[41].setProduction( Enum.lexType.PROCEDURE ) ;
product[41].setProduction( Enum.nonTerminals.ProcName ) ; product[41].setProduction( Enum.lexType.LPAREN ) ;
product[41].setProduction( Enum.nonTerminals.ParamList ) ; product[41].setProduction( Enum.lexType.RPAREN ) ;
product[41].setProduction( Enum.lexType.SEMI ) ; product[41].setProduction( Enum.nonTerminals.ProcDecPart ) ;
product[41].setProduction( Enum.nonTerminals.ProcBody ) ; product[41].setProduction( Enum.nonTerminals.ProcDecMore ) ;
product[42].setHead( Enum.nonTerminals.ProcDecMore ) ;
product[43].setHead( Enum.nonTerminals.ProcDecMore ) ; product[43].setProduction( Enum.nonTerminals.ProcDec ) ;
product[44].setHead( Enum.nonTerminals.ProcName ) ; product[44].setProduction( Enum.lexType.ID ) ;
product[45].setHead( Enum.nonTerminals.ParamList ) ;
product[46].setHead( Enum.nonTerminals.ParamList ) ; product[46].setProduction( Enum.nonTerminals.ParamDecList ) ;
product[47].setHead( Enum.nonTerminals.ParamDecList ) ; product[47].setProduction( Enum.nonTerminals.Param ) ;
product[47].setProduction( Enum.nonTerminals.ParamMore ) ;
product[48].setHead( Enum.nonTerminals.ParamMore ) ;
product[49].setHead( Enum.nonTerminals.ParamMore ) ; product[49].setProduction( Enum.lexType.SEMI ) ;
product[49].setProduction( Enum.nonTerminals.ParamDecList ) ;
product[50].setHead( Enum.nonTerminals.Param ) ; product[50].setProduction( Enum.nonTerminals.TypeDef ) ;
product[50].setProduction( Enum.nonTerminals.FormList ) ;
product[51].setHead( Enum.nonTerminals.Param ) ; product[51].setProduction( Enum.lexType.VAR ) ;
product[51].setProduction( Enum.nonTerminals.TypeDef ) ; product[51].setProduction( Enum.nonTerminals.FormList ) ;
product[52].setHead( Enum.nonTerminals.FormList ) ; product[52].setProduction( Enum.lexType.ID ) ;
product[52].setProduction( Enum.nonTerminals.FidMore ) ;
product[53].setHead( Enum.nonTerminals.FidMore ) ;
product[54].setHead( Enum.nonTerminals.FidMore ) ; product[54].setProduction( Enum.lexType.COMMA ) ;
product[54].setProduction( Enum.nonTerminals.FormList ) ;
product[55].setHead( Enum.nonTerminals.ProcDecPart ) ; product[55].setProduction( Enum.nonTerminals.DeclarePart ) ;
product[56].setHead( Enum.nonTerminals.ProcBody ) ; product[56].setProduction( Enum.nonTerminals.ProgramBody ) ;
product[57].setHead( Enum.nonTerminals.ProgramBody ) ; product[57].setProduction( Enum.lexType.BEGIN ) ;
product[57].setProduction( Enum.nonTerminals.StmList ) ; product[57].setProduction( Enum.lexType.END ) ;
product[58].setHead( Enum.nonTerminals.StmList ) ; product[58].setProduction( Enum.nonTerminals.Stm ) ;
product[58].setProduction( Enum.nonTerminals.StmMore ) ;
product[59].setHead( Enum.nonTerminals.StmMore ) ;
product[60].setHead( Enum.nonTerminals.StmMore ) ; product[60].setProduction( Enum.lexType.SEMI ) ;
product[60].setProduction( Enum.nonTerminals.StmList ) ;
product[61].setHead( Enum.nonTerminals.Stm ) ; product[61].setProduction( Enum.nonTerminals.ConditionalStm ) ;
product[62].setHead( Enum.nonTerminals.Stm ) ; product[62].setProduction( Enum.nonTerminals.LoopStm ) ;
product[63].setHead( Enum.nonTerminals.Stm ) ; product[63].setProduction( Enum.nonTerminals.InputStm ) ;
product[64].setHead( Enum.nonTerminals.Stm ) ; product[64].setProduction( Enum.nonTerminals.OutputStm ) ;
product[65].setHead( Enum.nonTerminals.Stm ) ; product[65].setProduction( Enum.nonTerminals.ReturnStm ) ;
product[66].setHead( Enum.nonTerminals.Stm ) ; product[66].setProduction( Enum.lexType.ID ) ;
product[66].setProduction( Enum.nonTerminals.AssCall ) ;
product[67].setHead( Enum.nonTerminals.AssCall ); product[67].setProduction( Enum.nonTerminals.AssignmentRest ) ;
product[68].setHead( Enum.nonTerminals.AssCall ) ; product[68].setProduction( Enum.nonTerminals.CallStmRest ) ;
product[69].setHead( Enum.nonTerminals.AssignmentRest ) ; product[69].setProduction( Enum.nonTerminals.VariMore ) ;
product[69].setProduction( Enum.lexType.ASSIGN ) ; product[69].setProduction( Enum.nonTerminals.Exp ) ;
product[70].setHead( Enum.nonTerminals.ConditionalStm ) ; product[70].setProduction( Enum.lexType.IF ) ;
product[70].setProduction( Enum.nonTerminals.RelExp ) ; product[70].setProduction( Enum.lexType.THEN ) ;
product[70].setProduction( Enum.nonTerminals.StmList ) ; product[70].setProduction( Enum.lexType.ELSE ) ;
product[70].setProduction( Enum.nonTerminals.StmList ) ; product[70].setProduction( Enum.lexType.FI ) ;
product[71].setHead( Enum.nonTerminals.LoopStm ) ; product[71].setProduction( Enum.lexType.WHILE ) ;
product[71].setProduction( Enum.nonTerminals.RelExp ) ; product[71].setProduction( Enum.lexType.DO ) ;
product[71].setProduction( Enum.nonTerminals.StmList ) ; product[71].setProduction( Enum.lexType.ENDWH ) ;
product[72].setHead( Enum.nonTerminals.InputStm ) ; product[72].setProduction( Enum.lexType.READ ) ;
product[72].setProduction( Enum.lexType.LPAREN ) ; product[72].setProduction( Enum.nonTerminals.Invar ) ;
product[72].setProduction( Enum.lexType.RPAREN ) ;
product[73].setHead( Enum.nonTerminals.Invar ) ; product[73].setProduction( Enum.lexType.ID ) ;
product[74].setHead( Enum.nonTerminals.OutputStm ) ; product[74].setProduction( Enum.lexType.WRITE ) ;
product[74].setProduction( Enum.lexType.LPAREN ) ; product[74].setProduction( Enum.nonTerminals.Exp ) ;
product[74].setProduction( Enum.lexType.RPAREN ) ;
product[75].setHead( Enum.nonTerminals.ReturnStm ) ; product[75].setProduction( Enum.lexType.RETURN ) ;
product[76].setHead( Enum.nonTerminals.CallStmRest ) ; product[76].setProduction( Enum.lexType.LPAREN );
product[76].setProduction( Enum.nonTerminals.ActParamList ) ; product[76].setProduction( Enum.lexType.RPAREN ) ;
product[77].setHead( Enum.nonTerminals.ActParamList ) ;
product[78].setHead( Enum.nonTerminals.ActParamList ) ; product[78].setProduction( Enum.nonTerminals.Exp ) ;
product[78].setProduction( Enum.nonTerminals.ActParamMore ) ;
product[79].setHead( Enum.nonTerminals.ActParamMore ) ;
product[80].setHead( Enum.nonTerminals.ActParamMore ) ; product[80].setProduction( Enum.lexType.COMMA ) ;
product[80].setProduction( Enum.nonTerminals.ActParamList ) ;
product[81].setHead( Enum.nonTerminals.RelExp ) ; product[81].setProduction( Enum.nonTerminals.Exp ) ;
product[81].setProduction( Enum.nonTerminals.OtherRelE ) ;
product[82].setHead( Enum.nonTerminals.OtherRelE ) ; product[82].setProduction( Enum.nonTerminals.CmpOp ) ;
product[82].setProduction( Enum.nonTerminals.Exp ) ;
product[83].setHead( Enum.nonTerminals.Exp ) ; product[83].setProduction( Enum.nonTerminals.Term ) ;
product[83].setProduction( Enum.nonTerminals.OtherTerm ) ;
product[84].setHead( Enum.nonTerminals.OtherTerm ) ;
product[85].setHead( Enum.nonTerminals.OtherTerm ) ; product[85].setProduction( Enum.nonTerminals.AddOp ) ;
product[85].setProduction( Enum.nonTerminals.Exp ) ;
product[86].setHead( Enum.nonTerminals.Term ) ; product[86].setProduction( Enum.nonTerminals.Factor ) ;
product[86].setProduction( Enum.nonTerminals.OtherFactor ) ;
product[87].setHead( Enum.nonTerminals.OtherFactor ) ;
product[88].setHead( Enum.nonTerminals.OtherFactor ) ; product[88].setProduction( Enum.nonTerminals.MultOp ) ;
product[88].setProduction( Enum.nonTerminals.Term ) ;
product[89].setHead( Enum.nonTerminals.Factor ) ; product[89].setProduction( Enum.lexType.LPAREN ) ;
product[89].setProduction( Enum.nonTerminals.Exp ) ; product[89].setProduction( Enum.lexType.RPAREN ) ;
product[90].setHead( Enum.nonTerminals.Factor ) ; product[90].setProduction( Enum.lexType.INTC ) ;
product[91].setHead( Enum.nonTerminals.Factor ) ; product[91].setProduction( Enum.nonTerminals.Variable ) ;
product[92].setHead( Enum.nonTerminals.Variable ) ; product[92].setProduction( Enum.lexType.ID ) ;
product[92].setProduction( Enum.nonTerminals.VariMore ) ;
product[93].setHead( Enum.nonTerminals.VariMore ) ;
product[94].setHead( Enum.nonTerminals.VariMore ) ; product[94].setProduction( Enum.lexType.LMIDPAREN ) ;
product[94].setProduction( Enum.nonTerminals.Exp ) ; product[94].setProduction( Enum.lexType.RMIDPAREN ) ;
product[95].setHead( Enum.nonTerminals.VariMore ) ; product[95].setProduction( Enum.lexType.DOT ) ;
product[95].setProduction( Enum.nonTerminals.FieldVar ) ;
product[96].setHead( Enum.nonTerminals.FieldVar ) ; product[96].setProduction( Enum.lexType.ID ) ;
product[96].setProduction( Enum.nonTerminals.FieldVarMore ) ;
product[97].setHead( Enum.nonTerminals.FieldVarMore ) ;
product[98].setHead( Enum.nonTerminals.FieldVarMore ) ; product[98].setProduction( Enum.lexType.LMIDPAREN ) ;
product[98].setProduction( Enum.nonTerminals.Exp ) ; product[98].setProduction( Enum.lexType.RMIDPAREN ) ;
product[99].setHead( Enum.nonTerminals.CmpOp ) ; product[99].setProduction( Enum.lexType.LT ) ;
product[100].setHead( Enum.nonTerminals.CmpOp ) ; product[100].setProduction( Enum.lexType.EQ ) ;
product[101].setHead( Enum.nonTerminals.AddOp ) ; product[101].setProduction( Enum.lexType.PLUS ) ;
product[102].setHead( Enum.nonTerminals.AddOp ) ; product[102].setProduction( Enum.lexType.MINUS ) ;
product[103].setHead( Enum.nonTerminals.MultOp ) ; product[103].setProduction( Enum.lexType.TIMES ) ;
product[104].setHead( Enum.nonTerminals.MultOp ) ; product[104].setProduction( Enum.lexType.OVER ) ;
}
}
treeNode.java:
package common;
public class treeNode {
int childNum ;
treeNode[] child = new treeNode[10] ;
treeNode father ;
int flag ; // 0 表示叶子节点
Enum.nonTerminals NonTerminal ;
Enum.lexType Terminal ;
String data ;
int x , y , width , length ;
public treeNode() {
childNum = 0 ;
}
public void setChild( treeNode node ) {
child[childNum] = new treeNode() ;
child[childNum] = node ;
childNum ++ ;
}
public void setFather( treeNode node ) {
father = new treeNode() ;
father = node ;
}
public void setflag( int FLAG ) {
flag = FLAG ;
}
public void setData( String DATA ) {
data = DATA ;
}
public void setNonTerminal( Enum.nonTerminals nonTerminal ) {
NonTerminal = nonTerminal ;
}
public void setTerminal( Enum.lexType terminal ) {
Terminal = terminal ;
}
public int getchildNum() {
return childNum ;
}
public treeNode getChild( int num ) {
return child[num] ;
}
public treeNode getFather() {
return father ;
}
public int getflag() {
return flag ;
}
public Enum.nonTerminals getNonTerminal() {
return NonTerminal ;
}
public Enum.lexType getTerminal() {
return Terminal ;
}
public String getData() {
return data ;
}
public void setX( int X ) {
x = X ;
}
public int getX() {
return x ;
}
public void setY( int Y ) {
y = Y ;
}
public int getY() {
return y ;
}
public void setWidth( int Width ) {
width = Width ;
}
public int getWidth() {
return width ;
}
public void setLength( int Length ) {
length = Length ;
}
public int getLength() {
return length ;
}
}
/**********************/
/* auther: lishicao*/
/* date : 2013.3.7*/
/* lexical analyzer */
/**********************/
package lex;
import java.io.* ;
import common.Enum ;
import common.Enum.lexType;
import common.Node ;
import common.Error ;
import java.util.* ;
public class scanner {
static int line , row , cur ;
static String Buffer ;
//public static Error error = new Error() ;
public scanner() {
line = 1 ;
row = 1 ;
cur = 0 ;
}
/************************************/
/*传入文件地址(string),读入源文件,返回string */
/* 功能是将源文件读入Buffer中 */
/************************************/
public static String readTxt( String filePath ) throws Exception {
FileReader file = new FileReader( filePath ) ;
BufferedReader reader = new BufferedReader( file ) ;
String temp = "" ;
while( reader.ready() ) {
temp += reader.readLine() ;
temp += '\n' ;
}
return temp ;
}
/************************************/
/* 取得下一个非空字符,并将该字符的下标赋值给cur */
/* 如果到了文件结束返回‘\0’ */
/************************************/
public static char getNextChar() {
int i ;
char ch = '\0' ;
if( cur == Buffer.length() - 1 ) {
ch = '\0' ;
return ch ;
}
for( i = cur ; i < Buffer.length() ; i ++ ) {
if( Buffer.charAt( i ) == '\n' ) {
line ++ ;
row = 1 ;
}
else if( Buffer.charAt( i ) == ' ' ) row ++ ;
else if( Buffer.charAt( i ) == '\t' ) row += 4 ;
else break ;
}
if( i != Buffer.length() ) {
ch = Buffer.charAt( i ) ;
}
else ch = '\0' ;
cur = i ;
return ch ;
}
/***********************************/
/* 识别数字 */
/***********************************/
public static String isNumber( char ch ){
String res = "" ;
int temp = cur ;
while( Buffer.charAt( temp ) >= '0' && Buffer.charAt( temp ) <= '9' ){
res += Buffer.charAt( temp ) ;
temp ++ ;
row ++ ;
}
if( ( Buffer.charAt( temp ) >= 'a' && Buffer.charAt( temp ) <= 'z' ) || ( Buffer.charAt( temp ) >= 'A' && Buffer.charAt( temp ) <= 'Z' ) )
res = null ;
cur = temp ;
return res ;
}
/***********************************/
/* 识别标示符或者保留字 */
/***********************************/
public static String isName( char ch ){
String res = "" ;
int temp = cur ;
while( ( Buffer.charAt( temp ) >= '0' && Buffer.charAt( temp ) <= '9' ) || ( Buffer.charAt( temp ) >= 'a' && Buffer.charAt( temp ) <= 'z' )
|| ( Buffer.charAt( temp ) >= 'A' && Buffer.charAt( temp ) <= 'Z' ) ) {
res += Buffer.charAt( temp ) ;
temp ++ ;
row ++ ;
}
cur = temp ;
return res ;
}
/***********************************/
/* 识别具体是哪个保留字 */
/***********************************/
public static lexType recognizeName( String name ){
switch( name ) {
case "program" : return Enum.lexType.PROGRAM ;
case "type" : return Enum.lexType.TYPE ;
case "var" : return Enum.lexType.VAR ;
case "procedure" : return Enum.lexType.PROCEDURE ;
case "begin" : return Enum.lexType.BEGIN ;
case "end" : return Enum.lexType.END ;
case "array" : return Enum.lexType.ARRAY ;
case "of" : return Enum.lexType.OF ;
case "record" : return Enum.lexType.RECORD ;
case "if" : return Enum.lexType.IF ;
case "then" : return Enum.lexType.THEN ;
case "else" : return Enum.lexType.ELSE ;
case "fi" : return Enum.lexType.FI ;
case "while" : return Enum.lexType.WHILE ;
case "do" : return Enum.lexType.DO ;
case "endwh" : return Enum.lexType.ENDWH ;
case "read" : return Enum.lexType.READ ;
case "write" : return Enum.lexType.WRITE ;
case "return" : return Enum.lexType.RETURN ;
case "integer" : return Enum.lexType.INTEGER ;
case "char" : return Enum.lexType.CHAR ;
default : return Enum.lexType.ID ;
}
}
/***********************************/
/* 识别该字符具体是哪个符号 */
/***********************************/
public static lexType recognizeSymbol( char symbol ) {
switch( symbol ) {
case '+' : return Enum.lexType.PLUS ;
case '-' : return Enum.lexType.MINUS ;
case '*' : return Enum.lexType.TIMES ;
case '/' : return Enum.lexType.OVER ;
case '(' : return Enum.lexType.LPAREN ;
case ')' : return Enum.lexType.RPAREN ;
case '.' : return Enum.lexType.DOT ;
case '[' : return Enum.lexType.LMIDPAREN ;
case ']' : return Enum.lexType.RMIDPAREN ;
case ';' : return Enum.lexType.SEMI ;
case ':' : return Enum.lexType.COLON ;
case ',' : return Enum.lexType.COMMA ;
case '<' : return Enum.lexType.LT ;
case '=' : return Enum.lexType.EQ ;
case '\'' : return Enum.lexType.CHARC ;
case '\0' : return Enum.lexType.ENDFILE ;
}
return null ;
}
/************************************/
/* 得到下一个 token */
/************************************/
public static Node getNextToken() {
Node now = new Node() ;
char c ;
c = getNextChar() ;
if( c == '\0' ) return null ;
now.setLine( line ) ;
now.setRow( row ) ;
if( c >= '0' && c <= '9' ){
String temp = isNumber( c ) ;
if( temp != null ) {
now.setData( temp ) ;
now.setType( Enum.lexType.INTC ) ;
}
else {
now = null ;
Error.setError( line , row , 1 ) ;
}
}
else if( ( c >= 'a' && c<= 'z' ) || ( c >= 'A' && c <= 'Z' ) ){
String temp = isName( c ) ;
if( temp != null ) now.setData( temp ) ;
else now = null ;
now.setType( recognizeName( temp ) ) ;
}
else if( c == '{' ) {
int i ;
int num = 1 ;
for( i = cur + 1 ; i < Buffer.length() ; i ++ ) {
if( Buffer.charAt( i ) == '{' ) num ++ ;
else if( Buffer.charAt( i ) == '}' ) num -- ;
if( Buffer.charAt( i ) == '\n' ) {
line ++ ;
row = 1 ;
}
else if( Buffer.charAt( i ) == '\t' ) row += 4 ;
else row ++ ;
if( num == 0 ) break ;
}
if( num != 0 ) {
cur = i ;
Error.setError( line , row , 1 ) ;
}
else cur = i + 1 ;
now.setData( null ) ;
}
else{
if( c == ':' && Buffer.charAt( cur + 1 ) == '=' ) {
now.setData( ":=" ) ;
now.setType( Enum.lexType.ASSIGN ) ;
cur += 2 ; row += 2 ;
}
else if( c == '.' && Buffer.charAt( cur + 1 ) == '.' ) {
now.setData( ".." ) ;
now.setType( Enum.lexType.UNDERANGE ) ;
cur += 2 ; row += 2 ;
}
else {
String temp = new String() ;
temp += c ;
now.setType( recognizeSymbol( c ) ) ;
now.setData( temp ) ;
if( now.getType() == null ) {
Error.setError( line , row , 1) ;
}
cur ++ ; row ++ ;
}
}
return now ;
}
/************************************/
/* 用String传入源文件地址 */
/* 返回一个链表,就是token链 */
/************************************/
public ArrayList< Node > getTokenList( String filePath ) throws Exception {
Buffer = readTxt( filePath ) ;
ArrayList< Node > TokenList = new ArrayList < Node > () ;
while( true ) {
Node temp = new Node () ;
temp = getNextToken() ;
if( temp == null ){
Node tmp = new Node() ;
tmp.setType( lexType.ENDFILE ) ;
tmp.setLine( line + 1 ) ;
tmp.setRow( 0 ) ;
TokenList.add( tmp ) ;
break ;
}
if( temp.getData() == null ) continue ;
if( Error.getFlag() ) break ;
TokenList.add( temp ) ;
}
return TokenList ;
}
}
package parser;
import java.util.*;
import lex.scanner ;
import common.* ;
import common.Enum ;
import common.Error ;
public class Parser {
static SNLproduct Product = new SNLproduct() ;
static SNLpredict Predict = new SNLpredict() ;
static scanner Scanner = new scanner() ;
static ArrayList < Node > TokenList = new ArrayList< Node > () ;
static int cur ;
public Parser() {
cur = 0 ;
}
/*****************/
/*递归地匹配一个非终极符*/
/*****************/
public static treeNode match( Enum.nonTerminals NonTerminal , treeNode father ) {
int i , j , choose = -1 ;
treeNode root = new treeNode() ;
Enum.nonTerminals temp ;
Enum.lexType curLex = TokenList.get(cur).getType() ;
root.setflag( 1 ) ;
root.setNonTerminal( NonTerminal ) ;
root.setFather( father ) ;
for( i = 1 ; i <= 104 ; i ++ ) {
int flag = 0 ;
temp = Product.product[i].getHead() ;
for( j = 0 ; j < Predict.predict[i].getPredictNum() ; j ++ ) {
if( curLex == Predict.predict[i].getPredict( j ) ) {
flag = 1 ;
break ;
}
}
if( flag == 1 && temp == NonTerminal ) {
choose = i ;
break ;
}
}
if( choose == -1 ) {
Error.setError( TokenList.get(cur).getLine() , TokenList.get(cur).getRow() , 2 ) ;
return null ;
}
else {
for( i = 0 ; i < Product.product[choose].getproductNum() ; i ++ ) {
if( Product.product[choose].getflag( i ) == 0 ) {
treeNode leaf = new treeNode() ;
leaf.setFather( father ) ;
leaf.setflag( 0 ) ;
leaf.setTerminal( Product.product[choose].getProductTerminal( i ) ) ;
leaf.setData( TokenList.get( cur ).getData() ) ;
root.setChild( leaf ) ;
cur ++ ;
}
else {
treeNode child ;
Enum.nonTerminals NonTerminals = Product.product[choose].getProductNonterminal(i) ;
child = match( NonTerminals , root ) ;
root.setChild( child ) ;
}
}
}
return root ;
}
/*********************/
/*得到一个语法分析树,返回树根*/
/*********************/
public static treeNode getTree( String filePath ) throws Exception {
TokenList = Scanner.getTokenList( filePath ) ;
if( Error.getFlag() == true ) {
return null ;
}
else {
treeNode root = new treeNode() ;
cur = 0 ;
root = match( Enum.nonTerminals.Program , root ) ;
if( TokenList.get(cur).getType() != Enum.lexType.ENDFILE ){
Error.setError( TokenList.get(cur).getLine() , TokenList.get(cur).getRow() , 2 ) ;
}
if( Error.getFlag() == true ) {
Error.printError() ;
return null ;
}
return root ;
}
}
}
package parser;
import common.treeNode;
import javax.swing.* ;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics ;
public class drawTree extends JFrame {
static int X ;
static int Space = 30 ;
static int Width , High ;
static NewPanel Panel ;
public static void main( String[] args ) throws Exception {
treeNode root = new treeNode() ;
Parser parser = new Parser() ;
root = parser.getTree( "source.txt" ) ;
drawtree( root ) ;
}
public drawTree() {
Panel = new NewPanel() ;
Panel.setPreferredSize( new Dimension( Width , High ) ) ;
JScrollPane pane = new JScrollPane( Panel );
add( pane ) ;
}
public static int getTreeInf( treeNode root , int Y ) {
int temp , Length , width = 0 ;
String str = "" ;
if( root.getflag() == 0 || ( root.getchildNum() == 0 ) ) {
if( root.getflag() == 0 ) str += root.getData() ;
else str += root.getNonTerminal() ;
Length = str.length() * 8 ;
width = Length + Space ;
root.setLength( Length ) ;
root.setWidth( width ) ;
root.setX( X ) ;
root.setY( Y ) ;
X += width ;
}
else {
str += root.getNonTerminal() ;
Length = str.length() * 8 ;
root.setLength( Length ) ;
root.setY( Y ) ;
temp = X ;
for( int i = 0 ; i < root.getchildNum() ; i ++ ) {
width += getTreeInf( root.getChild( i ) , Y + 150 ) ;
}
root.setX( temp + width / 2 - Length / 2 ) ;
if( width < Length ) {
width = Length / 2 + width / 2 ;
X += Length - width + Space ;
}
root.setWidth( width ) ;
}
return width ;
}
public static void drawtree( treeNode root ) {
X = 20 ;
High = getTreeInf( root , 20 ) ;
Width = X ;
Panel.Root = root ;
drawTree frame = new drawTree() ;
frame.setTitle( "语法分析树" ) ;
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ) ;
frame.setSize( 800 , 600 ) ;
frame.setVisible( true ) ;
}
}
class NewPanel extends JLabel {
public static treeNode Root ;
public void draw( treeNode root , Graphics g ) {
g.drawRect( root.getX() - 3 , root.getY() - 15 , root.getLength() + 1 , 20 ) ;
if( root.getflag() == 0 ) {
g.drawString( root.getData() , root.getX() , root.getY() ) ;
}
else {
g.drawString( "" + root.getNonTerminal() , root.getX() , root.getY() ) ;
if( root.getchildNum() != 0 ) {
for( int i = 0 ; i < root.getchildNum() ; i ++ ) {
g.drawLine( root.getX() + root.getLength() / 2 , root.getY() + 5 , root.getChild(i).getX() + root.getChild(i).getLength() / 2 , root.getChild(i).getY() - 15 ) ;
draw( root.getChild( i ) , g ) ;
}
}
}
}
public void paint( Graphics g ) {
super.paint( g ) ;
g.setColor( Color.white ) ;
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor( Color.black ) ;
draw( Root , g ) ;
}
}