Я делаю псевдоязык программирования на ANTLR и Java. Я столкнулся с несколькими проблемами, с которыми не могу справиться: [list] [*]If, else if и else: для каждого условия выполняется только один оператор, поэтому другие будут пропущены. Например: [code]else { show(a); show(b); }[/code]. Будет показан только . возврат int раньше работал, но теперь null.
[*]Мне не удалось создать arrayAccess, то есть под этим Я не могу сделать это: int b = array[1] или show(array[2]).
[*] Рассмотрите и вызовите следующую функцию: [code]public string fun(string a) { return "Haiii, " + a + "!\n"; }
string greet = fun("John") [/code] [code]greet[/code] остается пустым, в нем ничего нет.
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; [/code] Будем очень признательны за вашу помощь в выяснении проблем.