mirror of
https://github.com/JonathanFleischmann/CompilerULTIMATE.git
synced 2024-12-28 17:28:03 +00:00
Parser can do new Object(arg).method() now
This commit is contained in:
parent
c3a9dd1f1d
commit
9f6fc527f3
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
@ -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}
|
||||||
*
|
*
|
||||||
|
@ -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}
|
||||||
*
|
*
|
||||||
|
@ -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
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user