本文目录导读:

我来为您提供一个完整的Java解释器案例,包括一个简单的算术表达式解释器。
完整的Java表达式解释器
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/**
* 简单的Java表达式解释器
* 支持:加、减、乘、除、括号、变量赋值、函数调用
*/
public class SimpleInterpreter {
// 词法单元类型
private enum TokenType {
NUMBER, // 数字
PLUS, // +
MINUS, // -
MULTIPLY, // *
DIVIDE, // /
LPAREN, // (
RPAREN, // )
IDENTIFIER, // 标识符
ASSIGN, // =
SEMICOLON, // ;
PRINT, // print 关键字
EOF // 结束符
}
// 词法单元类
private static class Token {
TokenType type;
String value;
Token(TokenType type, String value) {
this.type = type;
this.value = value;
}
@Override
public String toString() {
return "Token(" + type + ", " + value + ")";
}
}
// 解释器主类
private static class Interpreter {
private List<Token> tokens;
private int current = 0;
private java.util.HashMap<String, Double> variables = new java.util.HashMap<>();
// 词法分析器
private List<Token> tokenize(String input) {
List<Token> result = new ArrayList<>();
int i = 0;
while (i < input.length()) {
char c = input.charAt(i);
// 跳过空白字符
if (Character.isWhitespace(c)) {
i++;
continue;
}
// 数字
if (Character.isDigit(c)) {
StringBuilder num = new StringBuilder();
while (i < input.length() &&
(Character.isDigit(input.charAt(i)) || input.charAt(i) == '.')) {
num.append(input.charAt(i));
i++;
}
result.add(new Token(TokenType.NUMBER, num.toString()));
continue;
}
// 标识符
if (Character.isLetter(c)) {
StringBuilder id = new StringBuilder();
while (i < input.length() &&
(Character.isLetterOrDigit(input.charAt(i)) || input.charAt(i) == '_')) {
id.append(input.charAt(i));
i++;
}
String identifier = id.toString();
if (identifier.equals("print")) {
result.add(new Token(TokenType.PRINT, identifier));
} else {
result.add(new Token(TokenType.IDENTIFIER, identifier));
}
continue;
}
// 运算符
switch (c) {
case '+': result.add(new Token(TokenType.PLUS, "+")); break;
case '-': result.add(new Token(TokenType.MINUS, "-")); break;
case '*': result.add(new Token(TokenType.MULTIPLY, "*")); break;
case '/': result.add(new Token(TokenType.DIVIDE, "/")); break;
case '(': result.add(new Token(TokenType.LPAREN, "(")); break;
case ')': result.add(new Token(TokenType.RPAREN, ")")); break;
case '=': result.add(new Token(TokenType.ASSIGN, "=")); break;
case ';': result.add(new Token(TokenType.SEMICOLON, ";")); break;
default:
throw new RuntimeException("无法识别的字符: " + c);
}
i++;
}
result.add(new Token(TokenType.EOF, ""));
return result;
}
// 语法分析器 - 使用递归下降解析
public Interpreter(String input) {
this.tokens = tokenize(input);
}
// 读取当前token
private Token peek() {
return tokens.get(current);
}
// 消费当前token并前进
private Token advance() {
Token token = tokens.get(current);
if (token.type != TokenType.EOF) {
current++;
}
return token;
}
// 匹配特定类型的token
private void match(TokenType type) {
Token token = peek();
if (token.type != type) {
throw new RuntimeException("期望 " + type + " 但得到 " + token.type);
}
advance();
}
// 解析程序(多个语句)
public void program() {
while (peek().type != TokenType.EOF) {
statement();
}
}
// 解析语句
private void statement() {
if (peek().type == TokenType.PRINT) {
// print 语句
advance(); // 消费print
double value = expression();
System.out.println("输出: " + value);
match(TokenType.SEMICOLON);
} else if (peek().type == TokenType.IDENTIFIER) {
// 赋值语句
String varName = advance().value; // 变量名
match(TokenType.ASSIGN); // =
double value = expression(); // 表达式
variables.put(varName, value);
match(TokenType.SEMICOLON); // ;
}
}
// 解析表达式 - 优先级最低
private double expression() {
return additive();
}
// 解析加法减法
private double additive() {
double result = multiplicative();
while (true) {
if (peek().type == TokenType.PLUS) {
advance();
result += multiplicative();
} else if (peek().type == TokenType.MINUS) {
advance();
result -= multiplicative();
} else {
break;
}
}
return result;
}
// 解析乘法除法
private double multiplicative() {
double result = primary();
while (true) {
if (peek().type == TokenType.MULTIPLY) {
advance();
result *= primary();
} else if (peek().type == TokenType.DIVIDE) {
advance();
double divisor = primary();
if (divisor == 0) {
throw new RuntimeException("除数不能为零");
}
result /= divisor;
} else {
break;
}
}
return result;
}
// 解析基本单元
private double primary() {
Token token = peek();
if (token.type == TokenType.NUMBER) {
advance();
return Double.parseDouble(token.value);
} else if (token.type == TokenType.IDENTIFIER) {
advance();
if (variables.containsKey(token.value)) {
return variables.get(token.value);
} else {
throw new RuntimeException("未定义的变量: " + token.value);
}
} else if (token.type == TokenType.LPAREN) {
advance();
double value = expression();
match(TokenType.RPAREN);
return value;
} else if (token.type == TokenType.MINUS) { // 一元负号
advance();
return -primary();
} else {
throw new RuntimeException("无效的语法");
}
}
}
// 主测试方法
public static void main(String[] args) {
System.out.println("=== 简单Java表达式解释器 ===");
System.out.println("支持操作: +, -, *, /, 括号, 变量赋值, print语句");
System.out.println("示例: \n");
// 测试案例
String[] testPrograms = {
"x = 10 + 5 * 2;", // 基本算术
"y = (x + 5) / 3;", // 括号和变量
"print x;", // 打印变量
"print y;", // 打印变量
"a = 3.14 * 2;", // 小数计算
"b = -a + 10;", // 负数和加法
"print a + b;", // 打印表达式结果
"result = ((2 + 3) * (4 - 1)) / 5;" // 复杂表达式
};
// 编程方式测试
try {
System.out.println("程序1执行: x = 10 + 5 * 2; y = (x + 5) / 3;");
Interpreter interpreter1 = new Interpreter("x = 10 + 5 * 2; y = (x + 5) / 3; print x; print y;");
interpreter1.program();
System.out.println("\n程序2执行: a = 3.14 * 2; b = -a + 10; print a + b;");
Interpreter interpreter2 = new Interpreter("a = 3.14 * 2; b = -a + 10; print a + b;");
interpreter2.program();
System.out.println("\n程序3执行: result = ((2 + 3) * (4 - 1)) / 5; print result;");
Interpreter interpreter3 = new Interpreter("result = ((2 + 3) * (4 - 1)) / 5; print result;");
interpreter3.program();
} catch (Exception e) {
System.err.println("解释器错误: " + e.getMessage());
}
// 交互式测试
System.out.println("\n=== 交互式测试模式 ===");
runInteractiveTests();
}
// 交互式测试
private static void runInteractiveTests() {
// 测试表达式和错误处理
String[] testCases = {
"x = 10;",
"x = x + 5;",
"print x;",
"y = x * 2 + 1;",
"print(x + y);",
"z = (x + y) / (y - x);",
"print z;"
};
Interpreter interpreter = null;
try {
// 模拟连续输入
StringBuilder program = new StringBuilder();
for (String stmt : testCases) {
program.append(stmt).append(" ");
System.out.println("输入: " + stmt);
}
interpreter = new Interpreter(program.toString());
System.out.println("执行结果:");
interpreter.program();
} catch (Exception e) {
System.err.println("错误: " + e.getMessage());
}
// 错误测试
System.out.println("\n=== 错误处理测试 ===");
String[] errorCases = {
"x = 10 / 0;", // 除零错误
"print y;", // 未定义变量
"x = (1 + 2;", // 括号不匹配
"1 + 2", // 缺少分号
"x == 5;" // 非法符号
};
for (String errorCase : errorCases) {
try {
System.out.println("测试: " + errorCase);
Interpreter badInterpreter = new Interpreter(errorCase);
badInterpreter.program();
} catch (RuntimeException e) {
System.out.println("捕获错误: " + e.getMessage());
}
System.out.println();
}
}
}
增强版:支持函数和更复杂的表达式
import java.util.*;
import java.util.function.BiFunction;
/**
* 扩展版解释器 - 支持函数调用和数学函数
*/
public class AdvancedInterpreter {
private Map<String, Double> variables = new HashMap<>();
private Map<String, BiFunction<Double, Double, Double>> functions = new HashMap<>();
public AdvancedInterpreter() {
// 注册数学函数
functions.put("pow", Math::pow);
functions.put("min", Math::min);
functions.put("max", Math::max);
functions.put("sqrt", (a, b) -> Math.sqrt(a));
functions.put("abs", (a, b) -> Math.abs(a));
}
/**
* 计算数学表达式
*/
public double evaluate(String expression) {
return new ExpressionParser(expression, variables, functions).parse();
}
/**
* 表达式解析器 - 支持函数调用
*/
private static class ExpressionParser {
private String input;
private int pos = 0;
private Map<String, Double> vars;
private Map<String, BiFunction<Double, Double, Double>> funcs;
public ExpressionParser(String input, Map<String, Double> vars,
Map<String, BiFunction<Double, Double, Double>> funcs) {
this.input = input;
this.vars = vars;
this.funcs = funcs;
}
/**
* 解析整个表达式
*/
public double parse() {
double result = expression();
if (pos < input.length()) {
throw new IllegalArgumentException("输入不是有效表达式: " + input);
}
return result;
}
/**
* 表达式 => 项 (+|-) 项
*/
private double expression() {
double left = term();
while (pos < input.length()) {
char c = input.charAt(pos);
if (c == '+' || c == '-') {
pos++;
double right = term();
if (c == '+') left += right;
else left -= right;
} else if (c == ',' || c == ')') {
break;
} else {
break;
}
}
return left;
}
/**
* 项 => 因子 (*|/) 因子
*/
private double term() {
double left = factor();
while (pos < input.length()) {
char c = input.charAt(pos);
if (c == '*' || c == '/') {
pos++;
double right = factor();
if (c == '*') {
left *= right;
} else {
if (right == 0) {
throw new ArithmeticException("除零错误");
}
left /= right;
}
} else {
break;
}
}
return left;
}
/**
* 因子 => 数字 | 变量 | 函数调用 | 括号表达式
*/
private double factor() {
// 跳过空白
skipWhitespace();
if (pos >= input.length()) {
throw new IllegalArgumentException("表达式未完成");
}
char c = input.charAt(pos);
// 处理一元负号
if (c == '-') {
pos++;
return -factor();
}
// 处理一元正号
if (c == '+') {
pos++;
return factor();
}
// 处理数字
if (Character.isDigit(c)) {
return number();
}
// 处理字母开头的标识符
if (Character.isLetter(c)) {
return identifier();
}
// 处理括号
if (c == '(') {
pos++;
double value = expression();
skipWhitespace();
if (pos >= input.length() || input.charAt(pos) != ')') {
throw new IllegalArgumentException("缺少右括号");
}
pos++;
return value;
}
throw new IllegalArgumentException("无法解析的字符: " + c);
}
/**
* 解析数字
*/
private double number() {
StringBuilder sb = new StringBuilder();
// 整数部分
while (pos < input.length() && Character.isDigit(input.charAt(pos))) {
sb.append(input.charAt(pos));
pos++;
}
// 小数部分
if (pos < input.length() && input.charAt(pos) == '.') {
sb.append('.');
pos++;
while (pos < input.length() && Character.isDigit(input.charAt(pos))) {
sb.append(input.charAt(pos));
pos++;
}
}
// 科学计数法
if (pos < input.length() && (input.charAt(pos) == 'e' || input.charAt(pos) == 'E')) {
sb.append(input.charAt(pos));
pos++;
if (pos < input.length() && (input.charAt(pos) == '+' || input.charAt(pos) == '-')) {
sb.append(input.charAt(pos));
pos++;
}
while (pos < input.length() && Character.isDigit(input.charAt(pos))) {
sb.append(input.charAt(pos));
pos++;
}
}
return Double.parseDouble(sb.toString());
}
/**
* 解析标识符(变量或函数)
*/
private double identifier() {
StringBuilder sb = new StringBuilder();
while (pos < input.length() && Character.isLetterOrDigit(input.charAt(pos))) {
sb.append(input.charAt(pos));
pos++;
}
String name = sb.toString();
// 检查是否是函数调用
skipWhitespace();
if (pos < input.length() && input.charAt(pos) == '(') {
pos++; // 跳过'('
return functionCall(name);
}
// 变量引用
if (vars.containsKey(name)) {
return vars.get(name);
}
// 内置常量
switch (name) {
case "pi": return Math.PI;
case "e": return Math.E;
default: throw new IllegalArgumentException("未定义的变量: " + name);
}
}
/**
* 解析函数调用
*/
private double functionCall(String name) {
List<Double> args = new ArrayList<>();
// 解析参数(可能为空)
skipWhitespace();
if (pos < input.length() && input.charAt(pos) == ')') {
pos++; // 空参数列表
} else {
// 解析第一个参数
args.add(expression());
// 解析更多参数
skipWhitespace();
while (pos < input.length() && input.charAt(pos) == ',') {
pos++;
args.add(expression());
skipWhitespace();
}
// 检查右括号
if (pos >= input.length() || input.charAt(pos) != ')') {
throw new IllegalArgumentException("函数调用缺少右括号");
}
pos++;
}
// 调用内置函数
switch (name) {
case "sin":
if (args.size() != 1) throw new IllegalArgumentException("sin需要1个参数");
return Math.sin(args.get(0));
case "cos":
if (args.size() != 1) throw new IllegalArgumentException("cos需要1个参数");
return Math.cos(args.get(0));
case "tan":
if (args.size() != 1) throw new IllegalArgumentException("tan需要1个参数");
return Math.tan(args.get(0));
case "sqrt":
if (args.size() != 1) throw new IllegalArgumentException("sqrt需要1个参数");
return Math.sqrt(args.get(0));
case "abs":
if (args.size() != 1) throw new IllegalArgumentException("abs需要1个参数");
return Math.abs(args.get(0));
case "pow":
if (args.size() != 2) throw new IllegalArgumentException("pow需要2个参数");
return Math.pow(args.get(0), args.get(1));
case "min":
if (args.size() != 2) throw new IllegalArgumentException("min需要2个参数");
return Math.min(args.get(0), args.get(1));
case "max":
if (args.size() != 2) throw new IllegalArgumentException("max需要2个参数");
return Math.max(args.get(0), args.get(1));
case "log":
if (args.size() != 1) throw new IllegalArgumentException("log需要1个参数");
return Math.log(args.get(0));
case "log10":
if (args.size() != 1) throw new IllegalArgumentException("log10需要1个参数");
return Math.log10(args.get(0));
default:
if (funcs.containsKey(name)) {
// 自定义函数
double first = args.size() > 0 ? args.get(0) : 0;
double second = args.size() > 1 ? args.get(1) : 0;
return funcs.get(name).apply(first, second);
}
throw new IllegalArgumentException("未定义的函数: " + name);
}
}
/**
* 跳过空白字符
*/
private void skipWhitespace() {
while (pos < input.length() && Character.isWhitespace(input.charAt(pos))) {
pos++;
}
}
}
/**
* 设置变量
*/
public void setVariable(String name, double value) {
variables.put(name, value);
}
/**
* 获取变量值
*/
public double getVariable(String name) {
return variables.getOrDefault(name, 0.0);
}
public static void main(String[] args) {
AdvancedInterpreter interpreter = new AdvancedInterpreter();
System.out.println("=== 增强版表达式解释器 ===");
System.out.println("支持: 算术运算, 函数调用, 变量, 数学常量\n");
// 测试用例
String[] tests = {
"2 + 3 * 4",
"(2 + 3) * 4",
"10 / 4",
"10.5 + 2.3",
"pow(2, 10)",
"sqrt(16)",
"sin(pi/2)",
"max(3, 7) + min(2, 5)",
"abs(-5) * cos(0)",
"log(e)",
"2^3 + 5",
"1e3 + 1e-1",
"pow(2, pow(2, 2))"
};
for (String test : tests) {
try {
double result = interpreter.evaluate(test);
System.out.printf("%-25s = %f%n", test, result);
} catch (Exception e) {
System.out.printf("%-25s = 错误: %s%n", test, e.getMessage());
}
}
// 变量测试
System.out.println("\n=== 变量使用测试 ===");
interpreter.setVariable("x", 10);
interpreter.setVariable("y", 3);
String[] variableTests = {
"x + y",
"x * y - 5",
"pow(x, 2) + y",
"sin(x) + cos(y)",
"(x + y) * (x - y)"
};
for (String test : variableTests) {
try {
double result = interpreter.evaluate(test);
System.out.printf("%-25s = %f%n", test, result);
} catch (Exception e) {
System.out.printf("%-25s = 错误: %s%n", test, e.getMessage());
}
}
}
}
使用示例和说明
简单解释器功能:
- 算术运算:加(+)、减(-)、乘(*)、除(/)
- 括号:支持嵌套括号改变运算优先级
- 变量:支持变量赋值和引用
- print语句:输出结果
- 错误处理:除零、未定义变量、语法错误
高级解释器功能:
- 数学函数:sin, cos, tan, sqrt, pow, log等
- 常量:pi和e
- 科学计数法
- 表达式验证
运行结果示例:
=== 简单Java表达式解释器 ===
程序1执行: x = 10 + 5 * 2; y = (x + 5) / 3; print x; print y;
输出: 20.0
输出: 8.333333333333334
这个案例展示了如何构建一个完整的表达式解释器,包括词法分析、语法分析和求值过程,您可以根据需要扩展功能,比如添加更多运算符、字符串处理功能或更复杂的语法结构。