Parser can do new Object(arg).method() now

This commit is contained in:
laurenz 2024-05-20 15:23:07 +02:00
parent c3a9dd1f1d
commit 9f6fc527f3
9 changed files with 556 additions and 435 deletions

View File

@ -34,7 +34,7 @@ stmt : 'if' '(' expr ')' block ('else' block)? #If
; ;
stmtexpr : methCall #MethodCall stmtexpr : methCall #MethodCall
| NEW type '(' args? ')' #New | newCall #New
; ;
expr : expr binaryOp expr #BinaryOperation expr : expr binaryOp expr #BinaryOperation
@ -48,14 +48,18 @@ expr : expr binaryOp expr #BinaryOperation
binaryOp : ADD | SUB | MUL | GT | LT | GE | LE | EQ | NE | AND | OR; binaryOp : ADD | SUB | MUL | GT | LT | GE | LE | EQ | NE | AND | OR;
unaryOp : SUB | NOT; unaryOp : SUB | NOT;
fieldVarAccess : (THIS '.')? (recipient '.')* id; fieldVarAccess : ((THIS '.')|(newCall '.'))? (recipient '.')* id;
assign : fieldVarAccess assignSign expr ; assign : fieldVarAccess assignSign expr ;
methCall : (THIS '.')? (recipient '.')* methName; methCall : ((THIS '.')|(newCall '.'))? (recipient '.')* methName;
newCall: NEW type '(' args? ')';
recipient : methName | id; recipient : methName | id;
methName : id '(' args? ')'; methName : id '(' args? ')';
args : expr (',' expr)*; args : expr (',' expr)*;
literal : NUMBER | BOOLEANLITERAL | CHARLITERAL; literal : NUMBER | BOOLEANLITERAL | CHARLITERAL;
id : IDENTIFIER; id : IDENTIFIER;

View File

@ -47,7 +47,7 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
Expression recipient = null; Expression recipient = null;
if (ctx.fieldVarAccess().recipient() != null) { if (ctx.fieldVarAccess().recipient() != null) {
List<DecafParser.RecipientContext> recipientList = ctx.fieldVarAccess().recipient(); List<DecafParser.RecipientContext> recipientList = ctx.fieldVarAccess().recipient();
recipient = generateRecursiveOwnerChain(recipientList, null); recipient = ExpressionGenerator.generateRecursiveOwnerChain(recipientList, ctx.fieldVarAccess().newCall() != null ? StatementGenerator.generateNew(ctx.fieldVarAccess().newCall()) : null);
} }
return new FieldVarAccess(isField, recipient, ctx.fieldVarAccess().id().IDENTIFIER().getText()); return new FieldVarAccess(isField, recipient, ctx.fieldVarAccess().id().IDENTIFIER().getText());
} }
@ -101,7 +101,7 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
Expression recursiveOwnerChain = null; Expression recursiveOwnerChain = null;
if (ctx.methCall().recipient() != null) { if (ctx.methCall().recipient() != null) {
List<DecafParser.RecipientContext> recipientList = ctx.methCall().recipient(); List<DecafParser.RecipientContext> recipientList = ctx.methCall().recipient();
recursiveOwnerChain = generateRecursiveOwnerChain(recipientList, null); recursiveOwnerChain = ExpressionGenerator.generateRecursiveOwnerChain(recipientList, ctx.methCall().newCall() != null ? StatementGenerator.generateNew(ctx.methCall().newCall()) : null);
} }
List<Expression> args = new ArrayList<>(); List<Expression> args = new ArrayList<>();
if (ctx.methCall().methName().args() != null) { if (ctx.methCall().methName().args() != null) {
@ -115,21 +115,11 @@ public class ExpressionGenerator extends DecafBaseVisitor<Expression> {
@Override @Override
public Expression visitNew(DecafParser.NewContext ctx) { public Expression visitNew(DecafParser.NewContext ctx) {
Type type = ASTGenerator.getType(ctx.type()); return StatementGenerator.generateNew(ctx.newCall());
List<Expression> args = new ArrayList<>();
if (ctx.args() != null) {
if (ctx.args() != null) {
for (var expr : ctx.args().expr()) {
Expression astExpr = expr.accept(this);
args.add(astExpr);
}
}
}
return new New(type, args);
} }
public static Expression generateRecursiveOwnerChain(List<DecafParser.RecipientContext> ctxList, FieldVarAccess recipient) { public static Expression generateRecursiveOwnerChain(List<DecafParser.RecipientContext> ctxList, Expression recipient) {
if (ctxList.isEmpty()) { if (ctxList.isEmpty()) {
return recipient; return recipient;
} }

View File

@ -6,6 +6,7 @@ import de.maishai.ast.Operator;
import de.maishai.ast.records.Assignment; import de.maishai.ast.records.Assignment;
import de.maishai.ast.records.Binary; import de.maishai.ast.records.Binary;
import de.maishai.ast.records.Block; import de.maishai.ast.records.Block;
import de.maishai.ast.records.BoolLiteral;
import de.maishai.ast.records.Break; import de.maishai.ast.records.Break;
import de.maishai.ast.records.Declaration; import de.maishai.ast.records.Declaration;
import de.maishai.ast.records.DoWhile; import de.maishai.ast.records.DoWhile;
@ -113,7 +114,7 @@ public class StatementGenerator extends DecafBaseVisitor<List<Statement>> {
Expression recursiveOwnerChain = null; Expression recursiveOwnerChain = null;
if (ctx.methCall().recipient() != null) { if (ctx.methCall().recipient() != null) {
List<DecafParser.RecipientContext> recipientList = ctx.methCall().recipient(); List<DecafParser.RecipientContext> recipientList = ctx.methCall().recipient();
recursiveOwnerChain = ExpressionGenerator.generateRecursiveOwnerChain(recipientList, null); recursiveOwnerChain = ExpressionGenerator.generateRecursiveOwnerChain(recipientList, ctx.methCall().newCall() != null ? generateNew(ctx.methCall().newCall()) : null);
} }
List<Expression> args = new ArrayList<>(); List<Expression> args = new ArrayList<>();
if (ctx.methCall().methName().args() != null) { if (ctx.methCall().methName().args() != null) {
@ -127,6 +128,10 @@ public class StatementGenerator extends DecafBaseVisitor<List<Statement>> {
@Override @Override
public List<Statement> visitNew(DecafParser.NewContext ctx) { public List<Statement> visitNew(DecafParser.NewContext ctx) {
return List.of( generateNew(ctx.newCall()));
}
public static New generateNew(DecafParser.NewCallContext ctx){
Type type = ASTGenerator.getType(ctx.type()); Type type = ASTGenerator.getType(ctx.type());
List<Expression> args = new ArrayList<>(); List<Expression> args = new ArrayList<>();
if (ctx.args() != null) { if (ctx.args() != null) {
@ -135,7 +140,7 @@ public class StatementGenerator extends DecafBaseVisitor<List<Statement>> {
args.add(astExpr); args.add(astExpr);
} }
} }
return List.of(new New(type, args)); return new New(type, args);
} }
public static Expression resolveFancyAssign(DecafParser.AssignSignContext ctx, FieldVarAccess fieldVarAccess, Expression expression) { public static Expression resolveFancyAssign(DecafParser.AssignSignContext ctx, FieldVarAccess fieldVarAccess, Expression expression) {

File diff suppressed because one or more lines are too long

View File

@ -444,6 +444,18 @@ public class DecafBaseListener implements DecafListener {
* <p>The default implementation does nothing.</p> * <p>The default implementation does nothing.</p>
*/ */
@Override public void exitMethCall(DecafParser.MethCallContext ctx) { } @Override public void exitMethCall(DecafParser.MethCallContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterNewCall(DecafParser.NewCallContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitNewCall(DecafParser.NewCallContext ctx) { }
/** /**
* {@inheritDoc} * {@inheritDoc}
* *

View File

@ -264,6 +264,13 @@ public class DecafBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements
* {@link #visitChildren} on {@code ctx}.</p> * {@link #visitChildren} on {@code ctx}.</p>
*/ */
@Override public T visitMethCall(DecafParser.MethCallContext ctx) { return visitChildren(ctx); } @Override public T visitMethCall(DecafParser.MethCallContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitNewCall(DecafParser.NewCallContext ctx) { return visitChildren(ctx); }
/** /**
* {@inheritDoc} * {@inheritDoc}
* *

View File

@ -401,6 +401,16 @@ public interface DecafListener extends ParseTreeListener {
* @param ctx the parse tree * @param ctx the parse tree
*/ */
void exitMethCall(DecafParser.MethCallContext ctx); void exitMethCall(DecafParser.MethCallContext ctx);
/**
* Enter a parse tree produced by {@link DecafParser#newCall}.
* @param ctx the parse tree
*/
void enterNewCall(DecafParser.NewCallContext ctx);
/**
* Exit a parse tree produced by {@link DecafParser#newCall}.
* @param ctx the parse tree
*/
void exitNewCall(DecafParser.NewCallContext ctx);
/** /**
* Enter a parse tree produced by {@link DecafParser#recipient}. * Enter a parse tree produced by {@link DecafParser#recipient}.
* @param ctx the parse tree * @param ctx the parse tree

File diff suppressed because it is too large Load Diff

View File

@ -243,6 +243,12 @@ public interface DecafVisitor<T> extends ParseTreeVisitor<T> {
* @return the visitor result * @return the visitor result
*/ */
T visitMethCall(DecafParser.MethCallContext ctx); T visitMethCall(DecafParser.MethCallContext ctx);
/**
* Visit a parse tree produced by {@link DecafParser#newCall}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitNewCall(DecafParser.NewCallContext ctx);
/** /**
* Visit a parse tree produced by {@link DecafParser#recipient}. * Visit a parse tree produced by {@link DecafParser#recipient}.
* @param ctx the parse tree * @param ctx the parse tree