There is a code of STInterpreter class that then gets the code:
package com.jdcs.st;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
import java.util.HashMap;
import java.util.Map;
import com.jdcs.st.generated.*;
public class STInterpreter {
private final Map<String, Object> symbolTable = new HashMap<>();
public void execute(String code) {
STLexer lexer = new STLexer(CharStreams.fromString(code));
STParser parser = new STParser(new CommonTokenStream(lexer));
ParseTree tree = parser.program();
new STVisitor().visit(tree);
}
private class STVisitor extends STBaseVisitor<Object> {
@Override
public Object visitAssignment(STParser.AssignmentContext ctx) {
String variable = ctx.IDENTIFIER().getText();
Object value = visit(ctx.expression());
System.out.println("Assigning " + value + " to " + variable); // Диагностика
symbolTable.put(variable, value);
// Вывод текущего состояния таблицы символов
System.out.println("Symbol Table: " + symbolTable);
return null;
}
@Override
public Object visitLiteral(STParser.LiteralContext ctx) {
if (ctx.INT() != null) return Integer.parseInt(ctx.INT().getText());
if (ctx.BOOL() != null) return Boolean.parseBoolean(ctx.BOOL().getText());
return null;
}
@Override
public Object visitExpression(STParser.ExpressionContext ctx) {
if (ctx.operator() == null) {
return visit(ctx.literal() != null ? ctx.literal() : ctx.IDENTIFIER());
}
Object left = visit(ctx.expression(0));
Object right = visit(ctx.expression(1));
String operator = ctx.operator().getText();
System.out.println("Left: " + left + ", Right: " + right + ", Operator: " + operator);
return evaluate(left, right, operator);
}
private Object evaluate(Object left, Object right, String operator) {
switch (operator) {
case "+" -> {
return (int) left + (int) right;
}
case "-" -> {
return (int) left - (int) right;
}
case "*" -> {
return (int) left * (int) right;
}
case "/" -> {
return (int) left / (int) right;
}
case "=" -> {
return left.equals(right);
}
case "<" -> {
return (int) left < (int) right;
}
case ">" -> {
return (int) left > (int) right;
}
}
throw new RuntimeException("Unsupported operator: " + operator);
}
@Override
public Object visitCondition(STParser.ConditionContext ctx) {
return visit(ctx.expression());
}
@Override
public Object visitIfStatement(STParser.IfStatementContext ctx) {
boolean condition = (boolean) visit(ctx.condition());
if (condition) {
ctx.statement().forEach(this::visit);
} else if (ctx.statement().size() > 1) {
visit(ctx.statement(1));
}
return null;
}
}
}
and for the code
STInterpreter interpreter = new STInterpreter();
String code = """
x := 10;
y := 20;
IF x < y THEN
z := x + y;
END_IF;
""";
interpreter.execute(code);
it's getting
Assigning 10 to x
Assigning 20 to y
Left: null, Right: null, Operator: <
Why assigning occurs, while not processed as the correct operation?
What I have to change to repair that:
@Override
public Object visitExpression(STParser.ExpressionContext ctx) {
if (ctx.operator() == null) {
// If Literal
if (ctx.literal() != null) {
return visit(ctx.literal());
}
// If identifier
if (ctx.IDENTIFIER() != null) {
String variable = ctx.IDENTIFIER().getText();
if (!symbolTable.containsKey(variable)) {
throw new RuntimeException("Variable '" + variable + "' is not defined.");
}
return symbolTable.get(variable);
}
}
// If binary expression
Object left = visit(ctx.expression(0));
Object right = visit(ctx.expression(1));
String operator = ctx.operator().getText();
System.out.println("Left: " + left + ", Right: " + right + ", Operator: " + operator);
return evaluate(left, right, operator);
}