词法分析:
BlockLexer.java:
package lab1;
import java.io.*;
public class BlockLexer{
private PushbackReader in = null;
private StringBuffer lexeme = new StringBuffer();
private char c;
private int line = 0;
private int column = 0;
public BlockLexer(String infile) {
PushbackReader reader = null;
try {
reader = new PushbackReader(new FileReader(infile));
} catch(IOException e) {
e.printStackTrace();
System.exit(-1);
}
in = reader;
}
//取得下一个字符
private void nextChar() {
try {
c = (char)in.read();
lexeme.append(c);
column++;
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
//回退一个字符(多读入的)
private void pushbackChar() {
try {
in.unread(lexeme.charAt(lexeme.length() - 1));
lexeme.deleteCharAt(lexeme.length() - 1);
column--;
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
//取得词法记号,并重置状态变量
private Token getToken(TokenType type) {
String t = lexeme.toString();
lexeme.setLength(0);
return new Token(type, t, line + 1, column - t.length() + 1);
}
//扔掉一个字符(此时单词应该还未开始,只需把长度设为0即可)
private void dropChar() {
lexeme.setLength(0);
}
//去空格、换行、回车等
private void removeSpace() {
this.nextChar();
while (Character.isWhitespace(c)) {
if (this.c == '\n') {
this.line++;
this.column = 0;
}
this.dropChar();
this.nextChar();
}
this.pushbackChar();
}
//识别标识符
private Token getID_or_Keywords() {
int s = 0;
while(true) {
switch(s) {
case 0:
nextChar();
if(Character.isLetterOrDigit(c) || c=='_') s = 0;
else s = 1;
break;
case 1:
this.pushbackChar();
String t = this.lexeme.toString();
if (t.equalsIgnoreCase("int")){
return getToken(TokenType.KEY_INT);
} else if(t.equalsIgnoreCase("boolean")) {
return getToken(TokenType.KEY_BOOLEAN);
} else if(t.equalsIgnoreCase("if")) {
return getToken(TokenType.KEY_IF);
} else if(t.equalsIgnoreCase("else")) {
return getToken(TokenType.KEY_ELSE);
} else if(t.equalsIgnoreCase("while")) {
return getToken(TokenType.KEY_WHILE);
} else if(t.equalsIgnoreCase("true")) {
return getToken(TokenType.BOOL_TRUE);
} else if(t.equalsIgnoreCase("false")) {
return getToken(TokenType.BOOL_FALSE);
} else {
return getToken(TokenType.IDENTIFIER);
}
}
}
}
/*****************************begin*******************************/
//识别整形常数,可能是十进制、八进制或十六进制
private Token getIntConst() {
int s=1;
if(this.c=='0'){
this.nextChar();
if(!Character.isDigit(c)&&c!='x') {
this.pushbackChar();
return getToken(TokenType.NUMBER_LITERAL);
}else if(this.c>=0&&this.c<=7) {
this.nextChar();
return getToken(TokenType.NUMBER_LITERAL);
}
else if(!Character.isDigit(c)&&c=='x') {
for(int i=0;i<4;i++) {
this.nextChar();
}
return getToken(TokenType.NUMBER_LITERAL);
}
this.nextChar();
this.pushbackChar();
}
else {
this.nextChar();
while(c>='0'&&c<='9') {
this.nextChar();
}
this.pushbackChar();
return getToken(TokenType.NUMBER_LITERAL);
}
return null;
}
//识别/,/=
//去多行注释/* */
//去单行注释//
private Token getDivide_or_removeComment() {
int s=1;
while(true) {
this.nextChar();
switch(s) {
case 1:
if(this.c=='/')s=2;
else if(this.c=='*')s=3;
else if(this.c=='=')return getToken(TokenType.DIVIDEEQUAL);
else {
this.pushbackChar();
return getToken(TokenType.DIVIDE);
}
break;
case 2:
if(this.c=='\n') {
this.line++;
this.column=0;
this.dropChar();
return null;
}else {
s=2;
}
break;
case 3:
if(this.c=='*')s=4;
else if(this.c=='\n') {
this.line++;
this.column=0;
s=3;
}else s=3;
break;
case 4:
if(this.c=='/') {
this.dropChar();
return null;
}else if(this.c=='\n') {
this.line++;
this.column=0;
s=3;
}else s=3;
break;
}
}
}
//识别+,++,+=
private Token getPlus() {
this.nextChar();
if(c=='+') {
return this.getToken(TokenType.PLUSPLUS);
}else if(c=='=') {
return this.getToken(TokenType.PLUSEQUAL);
}else{
this.pushbackChar();
return this.getToken(TokenType.PLUS);
}
}
//识别-,--,-=
private Token getMinus() {
this.nextChar();
if(c=='-') {
return this.getToken(TokenType.MINUSMINUS);
}else if(c=='=') {
return this.getToken(TokenType.MINUSEQUAL);
}else {
this.pushbackChar();
return this.getToken(TokenType.MINUS);
}
}
//识别*,*=
private Token getTimes() {
this.nextChar();
if(c=='=') {
return this.getToken(TokenType.TIMESEQUAL);
}else {
this.pushbackChar();
return this.getToken(TokenType.TIMES);
}
}
//识别%,%=
private Token getRemainder() {
this.nextChar();
if(c=='=') {
return this.getToken(TokenType.DIVIDEEQUAL);
}
else {
this.pushbackChar();
return this.getToken(TokenType.DIVIDE);
}
}
//识别>,>>,>=
private Token getGreater() {
this.nextChar();
if(c=='>') {
return this.getToken(TokenType.RIGHTSHIFT);
}else if(c=='=') {
return this.getToken(TokenType.GREATER_EQUAL);
}else {
this.pushbackChar();
return this.getToken(TokenType.GREATER);
}
}
//识别<,<<,<=
private Token getLess() {
this.nextChar();
if(c=='<') {
return this.getToken(TokenType.LEFTSHIFT);
}else if(c=='=') {
return this.getToken(TokenType.LESS_EQUAL);
}else {
this.pushbackChar();
return this.getToken(TokenType.LESS);
}
}
//识别=,==
private Token getAssign_or_Equal() {
this.nextChar();
if(c=='=') {
return this.getToken(TokenType.EQUAL);
}else {
this.pushbackChar();
return this.getToken(TokenType.ASSIGN);
}
}
//识别!,!=
private Token getNot_or_NotEqual() {
this.nextChar();
if(c=='=') {
return this.getToken(TokenType.NOT_EQUAL);
}else {
this.pushbackChar();
return this.getToken(TokenType.LOGICAL_NOT);
}
}
//识别&&
private Token getAnd() {
this.nextChar();
if(c=='&') {
return this.getToken(TokenType.LOGICAL_AND);
}else {
return null;
}
}
//识别||
private Token getOr() {
this.nextChar();
if(c=='|') {
return this.getToken(TokenType.LOGICAL_OR);
}else {
return null; }
}
/*****************************end*******************************/
//获取下一个token
public Token nextToken() {
Token token = null;
while(null == token) {
this.removeSpace();
this.nextChar();
if ( Character.isDigit(c) ) {
token = this.getIntConst();
} else if ( Character.isLetter(c) || c == '_'){
token = this.getID_or_Keywords();
} else if ( c == '+'){
token = this.getPlus();
} else if ( c == '-'){
token = this.getMinus();
} else if ( c == '*'){
token = this.getTimes();
} else if ( c == '/'){
token = this.getDivide_or_removeComment();
} else if ( c == '%'){
token = this.getRemainder();
} else if ( c == '!'){
token = this.getNot_or_NotEqual();
} else if ( c == '&'){
token = this.getAnd();
} else if ( c == '|'){
token = this.getOr();
} else if ( c == '='){
token = this.getAssign_or_Equal();
} else if ( c == '>'){
token = this.getGreater();
} else if ( c == '<'){
token = this.getLess();
} else if ( c == '('){
token = this.getToken(TokenType.LPAREN);
} else if ( c == ')'){
token = this.getToken(TokenType.RPAREN);
} else if ( c == '{'){
token = this.getToken(TokenType.LBRACKET);
} else if ( c == '}'){
token = this.getToken(TokenType.RBRACKET);
} else if ( c == ';'){
token = this.getToken(TokenType.SEMICOLON);
} else if (c == ','){
token = this.getToken(TokenType.COMMA);
} else if (c == '.'){
token = this.getToken(TokenType.DOT);
} else if ((c & 0xff) == 0xff) {
token = this.getToken(TokenType.EOF);
} else {
System.out.println(" get nextToken error!");
System.out.println(" find illegal character " + c);
System.out.println(" at line " + (line + 1) + ",colum " + column);
System.exit(1);
}
}
return token;
}
}
Main.java
package lab1;
import java.io.*;
import lab1.BlockLexer;
public class Main {
public static void main(String args[]) {
BlockLexer l = new BlockLexer("test/lab1test2.txt");
Token s = l.nextToken();
while (s != null && s.getType() != TokenType.EOF) {
System.out.println(s); s = l.nextToken();
}
}
}
Token.java:
package lab1;
public class Token {
private TokenType type;
private String token;
private int line;
private int column;
public Token(TokenType type, String token, int line, int column) {
this.type = type;
this.token = token;
this.line = line;
this.column = column;
}
public TokenType getType() {
return type;
}
public int getLine(){
return line;
}
public int getColumn(){
return column;
}
public String getLexeme(){
return token;
}
public String toString() {
return type + " " + token + " (" + line + ", " + column + ")";
}
}
TokenType.java:
package lab1;
public enum TokenType{
/** 忽略的词法单位 **/
IGNORE,
/** 变量 **/
IDENTIFIER, //标识符
/** 常量 **/
NUMBER_LITERAL, //整形常量
BOOL_TRUE, //true
BOOL_FALSE, //false
/** 保留字 */
KEY_INT, //int
KEY_BOOLEAN,//boolean
KEY_WHILE, //while
KEY_IF, //if
KEY_ELSE, //else
/** 算术运算符 */
PLUS, //+
PLUSPLUS, //++
PLUSEQUAL, //+=
MINUS, //-
MINUSMINUS, //--
MINUSEQUAL, //-=
TIMES, //*
TIMESEQUAL, //*=
DIVIDE, ///
DIVIDEEQUAL,//*=
REMAINDER, //%
REMAINDEREQUAL, //%=
/** 位运算符 */
LEFTSHIFT, //<<
RIGHTSHIFT, //>>
/** 关系运算符 */
LESS, //<
GREATER, //>
LESS_EQUAL, //<=
GREATER_EQUAL, //>=
NOT_EQUAL, //!=
EQUAL, //==
/** 逻辑运算符 */
LOGICAL_NOT, //!
LOGICAL_AND, //&&
LOGICAL_OR, //||
/** 赋值符号 */
ASSIGN, //=
/** 括号 */
LPAREN, //(
RPAREN, //)
LBRACKET, //{
RBRACKET, //}
/** 界符 */
COMMA, //逗号,
SEMICOLON, //分号;
DOT, //圆点.
/** 文件结尾符 */
EOF, //end of file
/** 非终结符号以及一些特殊的符号,语法分析时使用 */
Epsilon, //空
Start, //总的开始符号
Simpleblock, //{****}
Sequence, //语句序列
assignmentStatement,//赋值语句
Expression, //E
Expression_1, //E'
Term, //T
Term_1, //T'
Factor, //F
Boolexpression, //布尔表达式
Boolexpression_1,
Boolterm,
Boolterm_1,
Boolfactor,
relationalExpression, //关系表达式
relationalOperator, //关系运算符
ifStatement, //if语句
OptionalElse, //else语句(可选)
whileStatement //while语句
}
LL(1):
LabMain.java:
package lab2;
public class Lab2Main {
public static void main(String[] args) {
LL1 parser = new LL1();
parser.doParse("test/lab2test2.txt");
}
}
LL(1).java:
package lab2;
import java.util.*;
import lab1.*;
public class LL1 {
private BlockLexer lexer = null;
private Token lookAhead = null;
private Stack<TokenType> stack;
private LL1Table table = null;
public LL1() {
this.table = new LL1Table();
}
public void doParse(String filePath){
this.stack = new Stack<TokenType>();
this.lexer = new BlockLexer(filePath);
this.parse();
}
public void parse() {
/****************begin*******************/
StringBuffer buf=new StringBuffer();
buf.append("步骤\t分析栈\t当前符号\t动作\n");
int step=1;
this.stack.push(TokenType.EOF);
this.stack.push(TokenType.Simpleblock);
this.lookAhead=this.lexer.nextToken();
//TokenType x=this.stack.pop();
//System.out.print(x);
while(true) {
//System.out.print(this.lookAhead.getType());
//System.out.print("\n");
buf.append(step++ + "\t");
buf.append(this.stack + "\t");
buf.append(this.lookAhead.getType() + "\t");
TokenType x=this.stack.pop();
//System.out.print(x);
//System.out.print("\n");
if(this.isTerminal(x)) {
//System.out.print(step);
//break;
if(this.lookAhead.getType()!=TokenType.EOF) {
buf.append(x+"匹配");
buf.append("\n");
this.lookAhead=this.lexer.nextToken();
}
else if(this.lookAhead.getType()==TokenType.EOF) {
buf.append("success");
break;
}
//判断是否相等,注意是不是#
}else {
TokenType[] production =this.table.getItem(x, this.lookAhead.getType());
if(null==production) {
//报错
///System.out.print("414");
//System.out.print(production);
buf.append("error");
}else {
//System.out.print(production.length-1);
for(int i=0;i<production.length-1;i++) {
//System.out.print(production[i]);
//System.out.print("\n");
buf.append(production[i]+",");
}
buf.append(production[production.length-1]);
buf.append("\n");
//逆序进栈,注意空Epsilon
for(int i=production.length-1;i>=0;i--) {
if(production[i]!=TokenType.Epsilon) {
this.stack.push(production[i]);
}
}
}
}
}
System.out.print(buf);
/****************end*******************/
}
private String array2String(TokenType[] product) {
String ret = "";
for(TokenType type : product) {
ret += type + ",";
}
ret = ret.substring(0, ret.length() - 1);
return ret;
}
public boolean isTerminal(TokenType type) {
if(type.compareTo(TokenType.EOF) <= 0)
return true;
else
return false;
}
}
LL1Table.java:
package lab2;
import java.util.*;
import lab1.TokenType;
public class LL1Table {
HashMap<TokenType, HashMap<TokenType, TokenType[]>> table = null;
public LL1Table() {
this.table = new HashMap<TokenType, HashMap<TokenType, TokenType[]>>();
//select(Simpleblock-> {Sequence}) = {{}
TokenType[] BP1 = {TokenType.LBRACKET, TokenType.Sequence, TokenType.RBRACKET};
this.addItem(TokenType.Simpleblock, TokenType.LBRACKET, BP1);
//select(Sequence -> AssignmentStatement Sequence) = {IDENTIFIER}
TokenType[] SP1 = {TokenType.assignmentStatement, TokenType.Sequence};
this.addItem(TokenType.Sequence, TokenType.IDENTIFIER, SP1);
//select(Sequence -> epsilon) = {}}
TokenType[] SP2 = {TokenType.Epsilon};
this.addItem(TokenType.Sequence, TokenType.RBRACKET, SP2);
/***********************begin***************************/
//assignmentStatement → IDENTIFIER = expression
TokenType[] AP1 = {TokenType.IDENTIFIER,TokenType.ASSIGN,TokenType.Expression,TokenType.SEMICOLON};
this.addItem(TokenType.assignmentStatement, TokenType.IDENTIFIER, AP1);
//Expression → term expression_1
TokenType[] EP1 = {TokenType.Term,TokenType.Expression_1};
this.addItem(TokenType.Expression, TokenType.LPAREN, EP1);
this.addItem(TokenType.Expression, TokenType.IDENTIFIER, EP1);
this.addItem(TokenType.Expression, TokenType.NUMBER_LITERAL, EP1);
//Expression_1 → + term expression_1
TokenType[] EP2 = {TokenType.PLUS,TokenType.Term,TokenType.Expression_1};
this.addItem(TokenType.Expression_1, TokenType.PLUS, EP2);
//Expression_1 → - term expression_1
TokenType[] EP3 = {TokenType.MINUS,TokenType.Term,TokenType.Expression_1};
this.addItem(TokenType.Expression_1, TokenType.MINUS, EP3);
//Expression_1 → ε
TokenType[] EP4 = {TokenType.Epsilon};
this.addItem(TokenType.Expression_1, TokenType.SEMICOLON, EP4);
this.addItem(TokenType.Expression_1, TokenType.RPAREN, EP4);
//Term → factor term_1
TokenType[] TP1 = {TokenType.Factor,TokenType.Term_1};
this.addItem(TokenType.Term, TokenType.RPAREN, TP1);
this.addItem(TokenType.Term, TokenType.IDENTIFIER, TP1);
this.addItem(TokenType.Term, TokenType.NUMBER_LITERAL, TP1);
//Term_1 → * factor term_1
TokenType[] TP2 = {TokenType.TIMES,TokenType.Factor,TokenType.Term_1};
this.addItem(TokenType.Term_1, TokenType.TIMES, TP2);
//Term_1 → / factor term_1
TokenType[] TP3 = {TokenType.DIVIDE,TokenType.Factor,TokenType.Term_1};
this.addItem(TokenType.Term_1, TokenType.DIVIDE, TP3);
//Term_1 → % factor term_1
TokenType[] TP4 = {TokenType.REMAINDER,TokenType.Factor,TokenType.Term_1};
this.addItem(TokenType.Term_1, TokenType.REMAINDER, TP4);
//Term_1 → ε
TokenType[] TP5 = {TokenType.Epsilon};
this.addItem(TokenType.Term_1, TokenType.PLUS, TP5);
this.addItem(TokenType.Term_1, TokenType.MINUS, TP5);
this.addItem(TokenType.Term_1, TokenType.SEMICOLON, TP5);
this.addItem(TokenType.Term_1, TokenType.RPAREN, TP5);
//Factor → ( expression )
TokenType[] FP1 = {TokenType.LPAREN,TokenType.Expression,TokenType.RPAREN};
this.addItem(TokenType.Factor, TokenType.LPAREN, FP1);
//Factor → IDENTIFIER
TokenType[] FP2 = {TokenType.IDENTIFIER};
this.addItem(TokenType.Factor, TokenType.IDENTIFIER, FP2);
//Factor → NUMBER_LITERAL
TokenType[] FP3 = {TokenType.NUMBER_LITERAL};
this.addItem(TokenType.Factor, TokenType.NUMBER_LITERAL, FP3);
/***********************end***************************/
}
private void addItem(TokenType row, TokenType column, TokenType[] list) {
HashMap<TokenType, TokenType[]> map;
map = this.table.get(row);
if(map == null) map = new HashMap<TokenType, TokenType[]>();
map.put(column, list);
this.table.put(row, map);
}
public TokenType[] getItem(TokenType row, TokenType column){
HashMap<TokenType, TokenType[]> tmp = this.table.get(row);
if(tmp == null) return null;
TokenType[] list = tmp.get(column);
return list;
}
public String toString() {
StringBuffer buffer = new StringBuffer();
for(TokenType row : this.table.keySet()) {
for(TokenType column : this.table.get(row).keySet()) {
buffer.append("(" + row + "," + column + ") = " + this.getItem(row,column));
buffer.append("\n");
}
}
return buffer.toString();
}
}
LR:
Grammar.java:
package lab3;
import java.util.*;
import lab1.TokenType;
public class Grammar {
public static TokenType startSymbol;
public static HashMap<Integer,Production> productions;
static {
startSymbol = TokenType.Expression;
productions = new HashMap<Integer,Production>();
Production p = null;
//(0)S'->E
TokenType[] S1 = {TokenType.Expression};
p = new Production(TokenType.Start, S1);
productions.put(0, p);
//(1)E->E + T
TokenType[] E1 = {TokenType.Expression, TokenType.PLUS, TokenType.Term};
p = new Production(TokenType.Expression, E1);
productions.put(1, p);
//(2)E->T
TokenType[] E2 = {TokenType.Term};
p = new Production(TokenType.Expression, E2);
productions.put(2, p);
/************************begin******************************/
//3 T -> T * F
TokenType[] T1 = {TokenType.Term,TokenType.TIMES,TokenType.Factor};
p = new Production(TokenType.Term,T1);
productions.put(3, p);
//4 T -> F
TokenType[] T2 = {TokenType.Factor};
p = new Production(TokenType.Term,T2);
productions.put(4, p);
//5 F -> (E)
TokenType[] F1 = {TokenType.LPAREN,TokenType.Expression,TokenType.RPAREN};
p = new Production(TokenType.Factor,F1);
productions.put(5, p);
//6 F -> id
TokenType[] F2 = {TokenType.IDENTIFIER};
p = new Production(TokenType.Factor,F2);
productions.put(6, p);
/************************end******************************/
}
public static Production get(int i) {
// TODO Auto-generated method stub
return productions.get(i);
}
}
Lab3Main.java:
package lab3;
public class Lab3Main {
public static void main(String[] args) {
LR parser = new LR();
parser.doParse("test/lab3test1.txt");
}
}
LR.java:
package lab3;
import java.util.*;
import lab1.*;
public class LR {
private BlockLexer lexer = null;
private Token lookAhead = null;
private Stack<Integer> stateStack;
private Stack<TokenType> symbolStack;
private int length1;
public void doParse(String filePath){
this.stateStack = new Stack<Integer>();
this.symbolStack = new Stack<TokenType>();
this.lexer = new BlockLexer(filePath);
this.parse();
}
public void parse() {
/****************begin*******************/
/*Grammar.productions.get(0);
StringBuffer buf=new StringBuffer();
buf.append((TokenType[])Grammar.productions.get(0).getRight());
System.out.print(buf);*/
this.stateStack.push(0);
length1++;
this.symbolStack.push(TokenType.EOF);
this.lookAhead=this.lexer.nextToken();
int step=1;
StringBuffer buf=new StringBuffer();
buf.append("步骤\t状态栈\t符号栈\t当前符号\tAction\tGoto\n");
while(true) {
buf.append(step++ + "\t");
buf.append(this.stateStack + "\t");
buf.append(this.symbolStack + "\t");
buf.append(this.lookAhead.getType() + "\t");
int state=this.stateStack.peek();
LRTableEntry entry=LRTable.get(state, this.lookAhead.getType());
if(entry==null) {
buf.append("error");
break;
}
if(entry.getAction()=='a') {
buf.append("acc");
break;
}
if(entry.getAction()=='s') {
buf.append(entry.toString());
buf.append('\n');
this.stateStack.push(entry.getState());
length1++;
this.symbolStack.push(this.lookAhead.getType());
this.lookAhead=this.lexer.nextToken();
}
if(entry.getAction()=='r') {
buf.append(entry.toString());
buf.append('\t');
Integer[] state1=new Integer[10];
TokenType[] symbol1=new TokenType[10];
for(int i=0;i<length1;i++) {
state1[i]=this.stateStack.pop();
}
for(int i=length1-1;i>=0;i--) {
this.stateStack.push(state1[i]);
}
/*for(int i=0;i<length2;i++) {
symbol1[i]=this.symbolStack.pop();
System.out.print(symbol1[i]);
}*/
TokenType[] right=Grammar.productions.get(entry.getState()).getRight();
int length3=right.length;
for(int i=0;i<length3;i++) {
this.symbolStack.pop();
}
Integer count=0;
int flag=0;
int count2=0;
this.symbolStack.push(Grammar.productions.get(entry.getState()).getLeft());
for(int k=0;k<length1;k++) {
LRTableEntry entry1=LRTable.get(state1[k],Grammar.productions.get(entry.getState()).getLeft());
if(entry1!=null) {
count=entry1.getState();
break;
}
}
for(int i=0;i<length1;i++) {
if(state1[i]==count) {
flag=1;
count2=i;
}
}
if(flag==1) {
for(int i=1;i<=count2;i++) {
this.stateStack.pop();
length1--;
}
}
else {
this.stateStack.pop();
this.stateStack.push(count);
}
buf.append(count);
buf.append('\n');
}
}
System.out.print(buf);
/****************end*********************/
}
}
LRTable.java:
package lab3;
import java.util.*;
import lab1.TokenType;
public class LRTable {
private static HashMap<Integer, HashMap<TokenType, LRTableEntry>> table = null;
static {
table = new HashMap<Integer, HashMap<TokenType, LRTableEntry>>();
addItem(0, TokenType.IDENTIFIER, new LRTableEntry('s',5));
addItem(0, TokenType.LPAREN, new LRTableEntry('s',4));
addItem(0, TokenType.Expression, new LRTableEntry('g',1));
addItem(0, TokenType.Term, new LRTableEntry('g',2));
addItem(0, TokenType.Factor, new LRTableEntry('g',3));
addItem(1, TokenType.PLUS, new LRTableEntry('s',6));
addItem(1, TokenType.EOF, new LRTableEntry('a',0));
addItem(2, TokenType.TIMES, new LRTableEntry('s',7));
addItem(2, TokenType.PLUS, new LRTableEntry('r',2));
addItem(2, TokenType.RPAREN, new LRTableEntry('r',2));
addItem(2, TokenType.EOF, new LRTableEntry('r',2));
/************************begin******************************/
addItem(3, TokenType.PLUS, new LRTableEntry('r', 4));
addItem(3, TokenType.TIMES, new LRTableEntry('r', 4));
addItem(3, TokenType.RPAREN, new LRTableEntry('r', 4));
addItem(3, TokenType.EOF, new LRTableEntry('r', 4));
addItem(4, TokenType.IDENTIFIER, new LRTableEntry('s', 5));
addItem(4, TokenType.LPAREN, new LRTableEntry('s', 4));
addItem(4, TokenType.Expression, new LRTableEntry('g', 8));
addItem(4, TokenType.Term, new LRTableEntry('g', 2));
addItem(4, TokenType.Factor, new LRTableEntry('g', 3));
addItem(5, TokenType.PLUS, new LRTableEntry('r', 6));
addItem(5, TokenType.TIMES, new LRTableEntry('r', 6));
addItem(5, TokenType.RPAREN, new LRTableEntry('r', 6));
addItem(5, TokenType.EOF, new LRTableEntry('r', 6));
addItem(6, TokenType.IDENTIFIER, new LRTableEntry('s', 5));
addItem(6, TokenType.LPAREN, new LRTableEntry('s', 4));
addItem(6, TokenType.Term, new LRTableEntry('g', 9));
addItem(6, TokenType.Factor, new LRTableEntry('g', 3));
addItem(7, TokenType.IDENTIFIER, new LRTableEntry('s', 5));
addItem(7, TokenType.LPAREN, new LRTableEntry('s', 4));
addItem(7, TokenType.Factor, new LRTableEntry('g', 10));
addItem(8, TokenType.PLUS, new LRTableEntry('s', 6));
addItem(8, TokenType.RPAREN, new LRTableEntry('s', 11));
addItem(9, TokenType.PLUS, new LRTableEntry('r', 1));
addItem(9, TokenType.TIMES, new LRTableEntry('s', 7));
addItem(9, TokenType.RPAREN, new LRTableEntry('r', 1));
addItem(9, TokenType.EOF, new LRTableEntry('r', 1));
addItem(10, TokenType.PLUS, new LRTableEntry('r', 3));
addItem(10, TokenType.TIMES, new LRTableEntry('r', 3));
addItem(10, TokenType.RPAREN, new LRTableEntry('r', 3));
addItem(10, TokenType.EOF, new LRTableEntry('r', 3));
addItem(11, TokenType.PLUS, new LRTableEntry('r', 5));
addItem(11, TokenType.TIMES, new LRTableEntry('r', 5));
addItem(11, TokenType.RPAREN, new LRTableEntry('r', 5));
addItem(11, TokenType.EOF, new LRTableEntry('r', 5));
/************************end******************************/
}
private static void addItem(int row, TokenType column, LRTableEntry entry) {
HashMap<TokenType, LRTableEntry> tmp = null;
tmp = table.get(row);
if(tmp == null) tmp = new HashMap<TokenType, LRTableEntry>();
tmp.put(column, entry);
table.put(row, tmp);
}
public static LRTableEntry get(int row, TokenType column) {
HashMap<TokenType, LRTableEntry> tmp = null;
tmp = table.get(row);
if(tmp == null) return null;
return tmp.get(column);
}
}
LRTableEntry.java:
package lab3;
public class LRTableEntry {
private char action; //'s', shift; 'r',reduce; 'g',goto; 'a',acc
//if action = acc, state will be ignored
private int state; //state for shift and goto, product No. for reduce
public LRTableEntry(char action, int state) {
this.action = action;
this.state = state;
}
public char getAction() {
return this.action;
}
public int getState() {
return this.state;
}
public String toString() {
if('a' == this.action) return "acc";
if('g' == this.action) return this.state + "";
return this.action + "" + this.state;
}
}
Production.java:
package lab3;
import lab1.TokenType;
public class Production {
TokenType left;
TokenType[] right;
public Production(TokenType left, TokenType[] right) {
this.left = left;
this.right = right;
}
public TokenType getLeft() {
return this.left;
}
public TokenType[] getRight() {
return this.right;
}
}