JavaInterpreter模式
本文最后更新于:1 年前
语法规则也是类
1 - 表示语法树”节点”的类
public abstract class Node {
public abstract void parse(Context context) throws ParseException;
}
2 - 对应program的类
// <program> ::= program <command list>
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);
}
@Override
public String toString() {
return "[program " + commandListNode + "]";
}
}
3 - 对应command List的类
// <command list> ::= <command>* end
public class CommandListNode extends Node{
private ArrayList<Node> list = new ArrayList<>();
@Override
public void parse(Context context) throws ParseException {
while (true) {
if (context.CurrentToken() == null) {
throw new ParseException("Missing 'end'");
} else if (context.CurrentToken().equals("end")) {
context.skipToken("end");
break;
} else {
Node commandNode = new CommandNode();
commandNode.parse(context);
list.add(commandNode);
}
}
}
@Override
public String toString() {
return list.toString();
}
}
4 - 对应command的类
// <command> ::= <repeat command> | <primitive command>
public class CommandNode extends Node{
private Node node;
@Override
public void parse(Context context) throws ParseException {
if (context.CurrentToken().equals("repeat")){
node = new RepeatCommandNode();
node.parse(context);
} else {
node = new PrimitiveCommandNode();
node.parse(context);
}
}
@Override
public String toString() {
return node.toString();
}
}
5 - 对应repeat command的类
// <repeat command> ::= repeat <number> <command list>
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);
}
@Override
public String toString() {
return "[repeat " + number + " " + commandListNode + "]";
}
}
6 - 对应primitive command的类
// <primitive command> ::= go | right | left
public class PrimitiveCommandNode extends Node{
private String name;
@Override
public void parse(Context context) throws ParseException {
name = context.CurrentToken();
context.skipToken(name);
if (!name.equals("go") && !name.equals("right") && !name.equals("left")) {
throw new ParseException(name + "is undefined");
}
}
@Override
public String toString() {
return name;
}
}
7 - 表示语法解析上下文的类
public class Context {
private StringTokenizer tokenizer;
private String currentToken;
public Context(String text) {
tokenizer = new StringTokenizer(text);
nextToken();
}
public void nextToken() {
if (tokenizer.hasMoreElements()) {
currentToken = tokenizer.nextToken();
} else {
currentToken = null;
}
}
public String CurrentToken() {
return currentToken;
}
public void skipToken(String token) throws ParseException {
if (!token.equals(currentToken)) {
throw new ParseException("Warning: " + token +
" is expected, but " + currentToken + " is 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;
}
}
8 -表示语法解析中可能会发生的异常的类
public class ParseException extends Exception{
public ParseException(String msg) {
super(msg);
}
}
9 - 测试程序行为的类
public class Main {
public static void main(String[] args) {
String filePath = "Program文件路径";
try {
BufferedReader reader = new BufferedReader(new FileReader(filePath + "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 (IOException | ParseException e) {
e.printStackTrace();
}
}
}
10 - 输出示例
text ="program end"
node = [program []]
text ="program go end"
node = [program [go]]
text ="program go right go right go right go right end"
node = [program [go, right, go, right, go, right, go, right]]
text ="program repeat 4 go right end end"
node = [program [[repeat 4 [go, right]]]]
text ="program repeat 4 repeat 3 go right go left end right end end"
node = [program [[repeat 4 [[repeat 3 [go, right, go, left]], right]]]]
11 - Program.txt
program end
program go end
program go right go right go right go right end
program repeat 4 go right end end
program repeat 4 repeat 3 go right go left end right end end
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!