设计:
代码清单:
Node
public abstract class Node { public abstract void parse(Context context) throws ParseException; }
CommandListNode
public class CommandListNode extends Node{ private ArrayList list = new ArrayList(); @Override public void parse(Context context) throws ParseException { while(true){ if(context.getCurrentToken() ==null){ throw new ParseException("miss end"); }else if(context.getCurrentToken().equals("end")){ context.skipToken("end"); break; }else{ Node commandNode = new CommandNode(); commandNode.parse(context); list.add(commandNode); } } } @Override public String toString() { return list.toString(); } }
CommandNode
public class CommandNode extends Node{ private Node node; @Override public void parse(Context context) throws ParseException { if(context.getCurrentToken().equals("repeat")){ node = new RepeatCommandNode(); node.parse(context); }else{ node = new PrimitiveCommandNode(); node.parse(context); } } public String toString(){ return node.toString(); } }
Context
public class Context { private StringTokenizer tokenizer; private String currentToken; public Context(String texe){ tokenizer = new StringTokenizer(texe); nextToken(); } public String nextToken(){ if(tokenizer.hasMoreTokens()){ currentToken = tokenizer.nextToken(); }else { currentToken = null; } return currentToken; } public String getCurrentToken(){ return currentToken; } public void skipToken(String token) throws ParseException{ if(!token.equals(currentToken)){ throw new ParseException("warning:"+token+"is excepted, but" + currentToken+"id found"); } nextToken(); } public int currentNumber() throws ParseException{ int number = 0; try{ number = Integer.parseInt(currentToken); }catch (NumberFormatException e){ throw new ParseException("warning:"+e); } return number; } }
ParseException
public class ParseException extends Exception{ public ParseException(String msg){ super(msg); } }
PrimitiveCommandNode
public class PrimitiveCommandNode extends Node{ private String name; @Override public void parse(Context context) throws ParseException { name = context.getCurrentToken(); context.skipToken(name); if(!name.equals("go")&&!name.equals("right")&&!name.equals("left")){ throw new ParseException(name+"is underfined"); } } public String toString(){ return name; } }
ProgramNode
public class ProgramNode extends Node{ private Node commandListNode; @Override public void parse(Context context) throws ParseException { context.skipToken("program"); commandListNode = new CommandListNode(); commandListNode.parse(context); } public String toString(){ return "[program]"+commandListNode+"]"; } }
RepeatCommandNode
public class RepeatCommandNode extends Node{ private int number; private Node commandListNode; @Override public void parse(Context context) throws ParseException { context.skipToken("repeat"); number = context.currentNumber(); context.nextToken(); commandListNode = new CommandListNode(); commandListNode.parse(context); } public String toString(){ return "[repeat"+number+","+commandListNode+"]"; } }
Main
public class Main { public static void main(String[] args){ try { BufferedReader reader = new BufferedReader(new FileReader("d:/program.txt")); String text; while ((text = reader.readLine()) != null) { System.out.println("text = \"" + text + "\""); Node node = new ProgramNode(); node.parse(new Context(text)); System.out.println("node=" + node); } reader.close(); }catch (Exception e){ e.printStackTrace(); } } }