📄 lex.java
字号:
package cn.edu.buaa.scse.liyi.compile.tools;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PushbackReader;
import java.util.LinkedList;
import cn.edu.buaa.scse.liyi.compile.types.Output;
/**
*
* @author liyi
*/
public class Lex
{
//关键字
public static final int CONST=0;
public static final int INT=1;
public static final int IF=2;
public static final int ELSE=3;
public static final int WHILE=4;
public static final int VOID=5;
public static final int MAIN=6;
public static final int SCANF=7;
public static final int PRINTF=8;
public static final int RETURN=9;
public static final int BREAK=10;
public static final int CONTINUE=11;
//类型
public static final int INTEGER=12;
public static final int IDSY=13;
public static final int STRING=14;
//操作符
public static final int ADD=15;
public static final int MINUS=16;
public static final int MUL=17;
public static final int DIV=18;
public static final int EQUAL=19;
//符号
public static final int Lpar=20;
public static final int Rpar=21;
public static final int Lbra=22;
public static final int Rbra=23;
public static final int COMMA=24;
public static final int SEMICOLON=25;
//关系运算符
public static final int G=26; //大于号
public static final int L=27; //小于号
public static final int GE=28; //大于等于号
public static final int LE=29; //小于等于号
public static final int NE=30; //非等于号
public static final int EE=31; //等于号
public static final String[] KEYWORD={"const","int","if","else","while","void","main","scanf","printf","return","break","continue"};
private PushbackReader codereader=null;
private Output lop=null; //当前词法输出
private LinkedList<Output> list=null; //词法分析输出链
private boolean error=false;
public LinkedList<String> errorList=null; //错误列表
/**
* 词法分析器构造方法
* @param file
*/
public Lex(File file)
{
if(!file.exists()||!file.isFile())
{
return;
}
try
{
codereader=new PushbackReader(new FileReader(file),1);
}
catch(FileNotFoundException e)
{
e.printStackTrace();
}
}
public void setCodereader(PushbackReader codereader)
{
this.codereader=codereader;
}
public PushbackReader getCodereader()
{
return codereader;
}
public void setLop(Output lop)
{
this.lop=lop;
}
public Output getLop()
{
return lop;
}
public void setList(LinkedList<Output> list)
{
this.list=list;
}
public LinkedList<Output> getList()
{
return list;
}
public void setError(boolean error)
{
this.error=error;
}
public boolean isError()
{
return error;
}
/**
* 词法分析子程序
*/
public void analyze()
{
int c=0;
String ss=null;
char[] cc=new char[500];
int line=1;
list=new LinkedList<Output>();
errorList=new LinkedList<String>();
try
{
while((c=codereader.read())!=-1)
{
lop=new Output();
if(c==' '||c=='\t'||c=='\r')
{ //舍去各种空格符
continue;
}
else if(c=='\n')
{
++line;
continue;
}
else if(c=='+'||c=='-')
{ //读到+,-时
char a=(char)c; //把符号存为a,考查后面是否关联
c=codereader.read();
if(c==-1)
{
if(a=='+')
{ //当后面没有符号时,即为+或-本身,并结束词法分析
lop.setLine(line);
lop.setType(ADD);
lop.setWord("+");
}
else
{
lop.setLine(line);
lop.setType(MINUS);
lop.setWord("-");
}
list.add(lop);
break;
}
if(c<='9'&&c>'0'&&(list.getLast().getType()==EQUAL||list.getLast().getType()==Lpar))
{ //当加减号后面紧跟数字,且加减号前面是=号或(号时,视作有符号的数字;否则视为单个加减号
cc[0]=a;
int i=1;
for(;(c<='9'&&c>='0'&&c!=-1);c=codereader.read(),i++)
{
cc[i]=(char)c;
}
if(c==-1)
{
ss=new String(cc,0,i);
lop.setLine(line);
lop.setType(INTEGER);
lop.setWord(ss);
list.add(lop);
break;
}
else
{
ss=new String(cc,0,i);
codereader.unread(c);
lop.setLine(line);
lop.setType(INTEGER);
lop.setWord(ss);
}
}
else
{
codereader.unread(c);
if(a=='+')
{
lop.setLine(line);
lop.setType(ADD);
lop.setWord("+");
}
else
{
lop.setLine(line);
lop.setType(MINUS);
lop.setWord("-");
}
}
}
else if(c=='*')
{
lop.setLine(line);
lop.setType(MUL);
lop.setWord("*");
}
else if(c=='/')
{
c=codereader.read();
if(c=='*')
{
while((c=codereader.read())!=-1)
{
if(c=='*')
{
c=codereader.read();
if(c=='/')
{
break;
}
else
{
codereader.unread(c);
}
}
}
continue;
}
else if(c=='/')
{
while((c=codereader.read())!=-1)
{
if(c=='\n')
{
++line;
break;
}
}
continue;
}
else
{
codereader.unread(c);
lop.setLine(line);
lop.setType(DIV);
lop.setWord("/");
}
}
else if(c=='<'||c=='>'||c=='='||c=='!')
{ //当读到比较运算符时预读一个,考查是否仍为比较运算符,若是则组合为一个运算符,否则为单个算符
char a=(char)c;
c=codereader.read();
if(c=='=')
{
if(a=='<')
{
lop.setLine(line);
lop.setType(LE);
lop.setWord("<=");
}
else if(a=='>')
{
lop.setLine(line);
lop.setType(GE);
lop.setWord(">=");
}
else if(a=='=')
{
lop.setLine(line);
lop.setType(EE);
lop.setWord("==");
}
else if(a=='!')
{
lop.setLine(line);
lop.setType(NE);
lop.setWord("!=");
}
}
else
{
if(a=='<')
{
lop.setLine(line);
lop.setType(L);
lop.setWord("<");
}
else if(a=='>')
{
lop.setLine(line);
lop.setType(G);
lop.setWord(">");
}
else if(a=='=')
{
lop.setLine(line);
lop.setType(EQUAL);
lop.setWord("=");
}
else if(a=='!')
{
System.out.println("error'!'");
}
if(c==-1)
{
list.add(lop);
break;
}
codereader.unread(c);
}
} //当读到字母时,一直往下读到不是字母或数字为止,再考查是否为关键字,若是则输出对应关键字,否则为标识符
else if(c=='_'||c>='a'&&c<='z'||c>='A'&&c<='Z')
{
cc[0]=(char)c;
int i=1;
boolean kflag=false;
for(c=codereader.read();(c=='_'||c>='a'&&c<='z'||c>='A'&&c<='Z'||c<='9'&&c>='0')&&c!=-1;c=codereader.read(),i++)
{
cc[i]=(char)c;
}
ss=new String(cc,0,i);
//decide iskeyword?
for(i=0;i<KEYWORD.length;i++)
{
if(ss.equals(KEYWORD[i]))
{
lop.setLine(line);
lop.setType(i);
lop.setWord(ss);
kflag=true;
break;
}
}
if(kflag)
{
list.add(lop);
if(c==-1)
{
break;
}
codereader.unread(c);
continue;
}
else
{
lop.setLine(line);
lop.setType(IDSY);
lop.setWord(ss);
if(c==-1)
{
list.add(lop);
break;
}
codereader.unread(c);
}
}
else if(c<='9'&&c>='0')
{
cc[0]=(char) c;
int i=1;
for(c=codereader.read();(c<='9'&&c>='0'&&c!=-1);c=codereader.read(),i++)
{
cc[i]=(char)c;
}
ss=new String(cc,0,i);
lop.setLine(line);
lop.setType(INTEGER);
lop.setWord(ss);
if(c==-1)
{
list.add(lop);
break;
}
codereader.unread(c);
} //当读到双引号时,一直往下读到右双引号时为止,之前的都存为字符串
else if(c=='\"')
{
cc[0]=(char)c;
int i=1;
for(c=codereader.read();c!='\"'&&c!=-1;c=codereader.read(),i++)
{
cc[i]=(char)c;
}
cc[i]='\"';
ss=new String(cc,0,i+1);
lop.setLine(line);
lop.setType(STRING);
lop.setWord(ss);
if(c==-1)
{
list.add(lop);
break;
}
}
else if(c==',')
{
lop.setLine(line);
lop.setType(COMMA);
lop.setWord(",");
}
else if(c==';')
{
lop.setLine(line);
lop.setType(SEMICOLON);
lop.setWord(";");
}
else if(c=='(')
{
lop.setLine(line);
lop.setType(Lpar);
lop.setWord("(");
}
else if(c==')')
{
lop.setLine(line);
lop.setType(Rpar);
lop.setWord(")");
}
else if(c=='{')
{
lop.setLine(line);
lop.setType(Lbra);
lop.setWord("{");
}
else if(c=='}')
{
lop.setLine(line);
lop.setType(Rbra);
lop.setWord("}");
}
else
{
error=true;
this.errorList.add(Error.report(Error.ERR_NOTRECOGNIZED,line,(char)c));
continue;
}
list.add(lop);
}
codereader.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -