前言
最近无意中看见了王垠写的《怎样写一个解释器》,看完顿觉热血沸腾,大呼爽快,对于完全不懂编译原理,代码写的也不咋地的我居然看懂了……只能感叹大神不愧是大神,作为小白的我还有很长的路要走。
那么既然看了,就想着自己也写一个,于是就有了这篇文章。这篇文章会记录我写解释器的过程,以及写的时候遇到的问题。我会按照原文章的顺序一步一步写完它(如果我能写完的话……)
参考文章链接如下:http://www.jianshu.com/p/509505d3bd50
10-15号
二叉树
首先第一个是一个接收二叉树的函数,因为java不能直接接收二叉树,所以我们得将传入的String转为二叉树,这里我们使用递归。
代码如下:
public static int treeSum(String s){
if(isNumeric(s)){
return Integer.parseInt(s);
}else if(isTree(s)){
String s1,s2;
s1 = isTre.group(1).trim();
s2 = isTre.group(2).trim();
int v1 = treeSum(s1);
int v2 = treeSum(s2);
return v1 + v2;
}
return 0;
}
//判断是否为一棵二叉树,然后拆分
public static boolean isTree(String s){
Pattern pattern = Pattern.compile("\\((.*)(\\s\\([0-9]+\\s[0-9]+\\)|\\s[0-9]+)\\)");
isTre = pattern.matcher(s);
if( !isTre.matches() ){
return false;
}
return true;
}
//判断字符串是否为数字
public static boolean isNumeric(String str){
Pattern pattern = Pattern.compile("[0-9]*");
Matcher isNum = pattern.matcher(str);
if( !isNum.matches() ){
return false;
}
return true;
}
这里的思想简单来说就是判断传入的是否是数字,若是则return,若不是则递归。
运行结果如下:
这里比较麻烦是正则表达式的编写,其实挺好写的但我还是卡了好久……
还有就是
String s1,s2;
s1 = isTre.group(1).trim();
s2 = isTre.group(2).trim();
int v1 = treeSum(s1);
int v2 = treeSum(s2);
这里,这里如果直接写成treeSum(isTre.group(1).trim());的话,v2的值会被第二次递归的v2覆盖,导致结果不正确。
10-16号更新
计算器
计算器写完了,只是在之前的代码上改了下正则的匹配规则,还有return时候的符号判断
public class Calculate {
private static Matcher isTre;
public static void main(String[] args){
System.out.println("==>"+cal("(+ 1 2)"));
System.out.println("==>"+cal("(* 2 3)"));
System.out.println("==>"+cal("(* (+ 1 2) (+ 3 4))"));
System.out.println("==>"+cal("(* (+ 2 3) 1)"));
System.out.println("==>"+cal("(* 1 (+ 2 3))"));
}
public static int cal(String s){
if(isNumeric(s)){
return Integer.parseInt(s);
}else if(isTree(s)){
String s1,s2,s3;
s1 = isTre.group(1).trim();
s2 = isTre.group(2).trim();
s3 = isTre.group(3).trim();
int v1 = cal(s2);
int v2 = cal(s3);
switch (s1){
case "*":
return v1*v2;
case "+":
return v1+v2;
case "-":
return v1-v2;
case "/":
return v1/v2;
}
}
return 0;
}
//判断是否为一棵二叉树,然后拆分
public static boolean isTree(String s){
Pattern pattern = Pattern.compile("\\((\\*|-|/|\\+)(.*)(\\s\\([\\*|-|/|\\+]\\s[0-9]+\\s[0-9]+\\)|\\s[0-9]+)\\)");
isTre = pattern.matcher(s);
if( !isTre.matches() ){
return false;
}
return true;
}
//判断字符串是否为数字
public static boolean isNumeric(String str){
Pattern pattern = Pattern.compile("[0-9]*");
Matcher isNum = pattern.matcher(str);
if( !isNum.matches() ){
return false;
}
return true;
}
}
运行截图:
解释器
未完待续…