Множественные проблемы с обработкой посетителей ANTLRJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Множественные проблемы с обработкой посетителей ANTLR

Сообщение Anonymous »

Я делаю псевдоязык программирования на ANTLR и Java. Я столкнулся с несколькими проблемами, с которыми не могу справиться:
  • If, else if и else: для каждого условия выполняется только один оператор, поэтому другие будут пропущены. Например:

    Код: Выделить всё

    else { show(a); show(b); }
    .
    Будет показан только . возврат int раньше работал, но теперь null.
  • Мне не удалось создать arrayAccess, то есть под этим Я не могу сделать это: int b = array[1] или show(array[2]).
  • Рассмотрите и вызовите следующую функцию:

    Код: Выделить всё

    public string fun(string a) {
    return "Haiii, " + a + "!\n";
    }
    
    string greet = fun("John")
    
    остается пустым, в нем ничего нет.
Вот мой GrammarsVisitor.java:

Код: Выделить всё

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import java.util.List;
import java.util.ArrayList;

public class GrammarsVisitor extends GrammarBaseVisitor {
private final Stack scopes = new Stack();
private final Map functions = new HashMap();

public GrammarsVisitor() {
// Push the global scope
scopes.push(new HashMap());
}

@Override
public Object visitVariable(GrammarParser.VariableContext ctx) {
String type = ctx.TYPE().getText();
String variableName = ctx.ID().getText();
Object value = null;

// If the variable is initialized
if (ctx.expression() != null) {
value = visitExpression(ctx.expression());
}

// Storing the variable in the current scope based on its type
switch (type) {
case "int":
if (value == null) {
value = 0;
} else {
value = Integer.parseInt(value.toString());
}
break;
case "float":
if (value == null) {
value = 0.0f;
} else {
value = Float.parseFloat(value.toString());
}
break;
case "string":
if (value == null) {
value = "";
} else {
value = value.toString();
}
break;
case "bool":
if (value == null) {
value = false;
} else {
value = Boolean.parseBoolean(value.toString());
}
break;
default:
throw new RuntimeException("Unknown type: " + type);
}

// Adding the variable to the current scope
if (scopes.peek().containsKey(variableName)) {
throw new RuntimeException("Variable already declared in the current scope: " + variableName);
}
scopes.peek().put(variableName, value);
System.out.println("Variable declared: " + type + " " + variableName + " = " + value);
return null;
}

@Override
public Object visitArray(GrammarParser.ArrayContext ctx) {
String type = ctx.TYPE() != null ? ctx.TYPE().getText() : ctx.ID(0).getText();
String arrayName = ctx.ID(0).getText();
java.util.List array = new java.util.ArrayList();

// If the array is initialized
if (ctx.arrayInit() != null) {
for (GrammarParser.ExpressionContext exprCtx : ctx.arrayInit().expression()) {
array.add(visitExpression(exprCtx));
}
}

// Adding the array to the current scope
if (scopes.peek().containsKey(arrayName)) {
throw new RuntimeException("Array already declared in the current scope: " + arrayName);
}
scopes.peek().put(arrayName, array);
System.out.println("Array declared: " + type + "[] " + arrayName + " = "  + array);
return null;
}

public Object visitExpression(GrammarParser.ExpressionContext ctx) {
if (ctx.functionCall() != null) {
return visitFunctionCall(ctx.functionCall());
}
if (ctx.BOOL() != null) {
return Boolean.parseBoolean(ctx.BOOL().getText());
} else if (ctx.INT() != null) {
return Integer.parseInt(ctx.INT().getText());
} else if (ctx.FLOAT() != null) {
return Float.parseFloat(ctx.FLOAT().getText());
} else if (ctx.STRING() != null) {
return ctx.STRING().getText()
.replace("\"", "")
.replace("\\n", "\n")
.replace("\\t", "\t");
} else if (ctx.ID() != null) {
String variableName = ctx.ID().getText();
for (int i = scopes.size() - 1; i >= 0; i--) {
if (scopes.get(i).containsKey(variableName)) {
return scopes.get(i).get(variableName);
}
}
throw new RuntimeException("Undefined variable: " + variableName);
} else if (ctx.getChildCount() == 3 && ctx.getChild(0).getText().equals("(") && ctx.getChild(2).getText().equals(")")) {
return visitExpression(ctx.expression(0));
} else if (ctx.getChildCount() == 2 && ctx.getChild(0).getText().equals("!")) {
return !(Boolean) visitExpression(ctx.expression(0));
} else if (ctx.getChildCount() == 3) {
Object left = visitExpression(ctx.expression(0));
Object right = visitExpression(ctx.expression(1));
String operator = ctx.getChild(1).getText();

switch (operator) {
case "%":
if (left instanceof Integer && right instanceof Integer) {
return (Integer) left % (Integer) right;
} else if (left instanceof Float || right instanceof Float) {
return Float.parseFloat(left.toString()) % Float.parseFloat(right.toString());
}
break;
case "+":
if (left instanceof Integer && right instanceof Integer) {
return (Integer) left + (Integer) right;
} else if (left instanceof Float || right instanceof Float) {
return Float.parseFloat(left.toString()) + Float.parseFloat(right.toString());
} else if (left instanceof String || right instanceof String) {
return left.toString() + right.toString();
}
break;
case "-":
if (left instanceof Integer && right instanceof Integer) {
return (Integer) left - (Integer) right;
} else if (left instanceof Float || right instanceof Float) {
return Float.parseFloat(left.toString()) - Float.parseFloat(right.toString());
}
break;
case "*":
if (left instanceof Integer && right instanceof Integer) {
return (Integer) left * (Integer) right;
} else if (left instanceof Float || right instanceof Float) {
return Float.parseFloat(left.toString()) * Float.parseFloat(right.toString());
}
break;
case "/":
if (left instanceof Integer && right instanceof Integer) {
return (Integer) left / (Integer) right;
} else if (left instanceof Float || right instanceof Float) {
return Float.parseFloat(left.toString()) / Float.parseFloat(right.toString());
}
break;
case "&&":
return (Boolean) left && (Boolean) right;
case "||":
return (Boolean) left || (Boolean) right;
case "==":
return left.equals(right);
case "!=" :
return !left.equals(right);
case "":
if (left instanceof Integer && right instanceof Integer) {
return (Integer) left > (Integer) right;
} else if (left instanceof Float || right instanceof Float) {
return Float.parseFloat(left.toString()) > Float.parseFloat(right.toString());
}
break;
case "=" :
if (left instanceof Integer && right instanceof Integer) {
return (Integer) left >= (Integer) right;
} else if (left instanceof Float || right instanceof Float) {
return Float.parseFloat(left.toString()) >= Float.parseFloat(right.toString());
}
break;
default:
throw new RuntimeException("Unsupported operator: " + operator);
}
}
throw new RuntimeException("Invalid expression: " + ctx.getText());
}

@Override
public Object visitFunction(GrammarParser.FunctionContext ctx) {
String functionName = ctx.ID(0).getText();
List paramNames = new ArrayList();
if (ctx.TYPE() != null && ctx.ID().size() > 1) {
for (int i = 1; i < ctx.ID().size(); i++) {
paramNames.add(ctx.ID(i).getText());
}
}
functions.put(functionName, new FunctionDefinition(ctx, paramNames));
System.out.println("Function declared: " + functionName);
return null;
}

@Override
public Object visitFunctionCall(GrammarParser.FunctionCallContext ctx) {
String functionName = ctx.ID(0).getText();
FunctionDefinition functionDef = functions.get(functionName);
if (functionDef == null) {
throw new RuntimeException("Undefined function: " + functionName);
}

// Creating a new scope for function call
scopes.push(new HashMap());

// Assign parameter values to new scope
List args = ctx.expression();
for (int i = 0; i < args.size(); i++) {
String paramName = functionDef.paramNames.get(i);
Object paramValue = visitExpression(args.get(i));
scopes.peek().put(paramName, paramValue);
}

// Execute the function body
Object returnValue = null;
for (GrammarParser.StatementContext stmtCtx : functionDef.functionCtx.statement()) {
returnValue = visit(stmtCtx);
if (returnValue != null) {
break;
}
}

// Pop the function scope
scopes.pop();
return returnValue;
}

@Override
public Object visitReturnStatement(GrammarParser.ReturnStatementContext ctx) {
return visitExpression(ctx.expression());
}

@Override
public Object visitShow(GrammarParser.ShowContext ctx) {
Object value = visitExpression(ctx.expression());
System.out.println(value);
return null;
}

@Override
public Object visitLoop(GrammarParser.LoopContext ctx) {
String loopVariable = ctx.ID().getText();
Object start = visitExpression(ctx.expression(0));
Object end = visitExpression(ctx.expression(1));

if (!(start instanceof Integer) || !(end instanceof Integer)) {
throw new RuntimeException("The 'for' loop must have integer start and end values: "  + ctx.getText());
}

int startValue = (Integer) start;
int endValue = (Integer) end;

if (startValue ' | '=' | ' channel(HIDDEN);
LINE_COMMENT : '//' ~[\r\n]* -> skip;
BLOCK_COMMENT : '/*' .*? '*/' -> skip;
Будем очень признательны за вашу помощь в выяснении проблем.

Подробнее здесь: https://stackoverflow.com/questions/791 ... processing
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»