@Override public String visitGameinit(@NotNull DiceGameParser.GameinitContext ctx) { if (ctx.ASSN != null) { return ctx.ASSN.accept(this) + "\n"; } if (ctx.FROM != null && ctx.TO != null) { return "self.min = " + ctx.FROM.getText() + "\nself.max = " + ctx.TO.getText(); } if (ctx.FROM != null) { return "self.min = " + ctx.FROM.getText() + "\nself.max = " + ctx.FROM.getText(); } if (ctx.DICEINIT != null) { StringBuilder result = new StringBuilder(); result.append("self.dices = ["); for (ParseTree diceInit : ctx.children) { if (diceInit.getClass() == DiceGameParser.DiceinitContext.class) { result.append(diceInit.accept(this) + ", "); } } result.append("]\n"); return result.toString(); } if (ctx.COND != null) { return "def isRunning(self): return (" + ctx.COND.accept(this) + ")"; } return "visitGameinit"; }
@Override public String visitDiceobjects(@NotNull DiceGameParser.DiceobjectsContext ctx) { if (ctx.ALL != null) { return "self.dices"; } if (ctx.LAST != null) { String ret = "["; for (ParseTree val : ctx.children) { if (val.getClass() == DiceGameParser.DiceobjectContext.class) { ret += val.accept(this) + ", "; } } ret += "]"; return ret; } return "visitDiceobjects"; }
public static AstNode createAst(String program) { ParseTree tree = createParseTree(program); EKPVisitor<AstNode> visitor = new AstCreationVisitor(); return tree.accept(visitor); }
@Override public String visitGame(@NotNull DiceGameParser.GameContext ctx) { String imports = "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\nimport random\n\n"; StringBuilder playerClass = new StringBuilder(); playerClass.append("class Player:\n"); playerClass.append( indent( "def __str__(self): return self.name + ', ' + ', '.join(map(str, [value for key, value in self.__dict__.items() if key not in ['name']]))\n")); StringBuilder playerInit = new StringBuilder(); playerInit.append("def __init__(self, name): "); playerInit.append("self.name = name; "); StringBuilder playerActive = new StringBuilder(); for (ParseTree init : ctx.children) { if (init.getClass() == DiceGameParser.PlayerinitContext.class) { if (((DiceGameParser.PlayerinitContext) init).ASSN != null) { playerInit.append(init.accept(this) + "; "); } else if (((DiceGameParser.PlayerinitContext) init).PLAYERACTIVECOND != null) { playerActive.append("def isActive(self): "); playerActive.append(init.accept(this) + "; "); } } } playerClass.append(indent(playerInit.toString()) + "\n"); playerClass.append(indent(playerActive.toString()) + "\n"); playerClass.append(indent("\n")); StringBuilder diceClass = new StringBuilder(); diceClass.append("class Dice:\n"); diceClass.append( indent( "def __init__(self, name, faces): self.name = name; self.faces = faces; self.roll()")); diceClass.append(indent("def roll(self): self.value = random.choice(self.faces)")); diceClass.append(indent("def __str__(self): return self.name+': '+str(self.value)")); diceClass.append(indent("\n")); StringBuilder gameClass = new StringBuilder(); gameClass.append("class Game:\n"); gameClass.append(indent("# Static methods")); gameClass.append( indent( "def status(self): return 'Status[name, ' + ', '.join([key for key, value in self.players[0].__dict__.items() if key not in ['name']]).lower()+']: '+' - '.join(map(str, self.players))")); gameClass.append( indent( "def rightPlayer(self): return self.players[ (self.players.index(self.activePlayer) - 1) % self.playerCount]")); gameClass.append( indent( "def leftPlayer(self): return self.players[ (self.players.index(self.activePlayer) + 1) % self.playerCount]")); gameClass.append(indent("def playerNum (self, num): return self.players[num]")); gameClass.append(indent("def rollDices(self): map(Dice.roll, self.dices)")); gameClass.append( indent( "def sortDices(self, desc=False): self.dices = sorted(self.dices, key=lambda dice: dice.value, reverse=desc)")); StringBuilder gameSetupMethod = new StringBuilder(); gameSetupMethod.append("def setup(self):\n"); gameSetupMethod.append( indent("self.playerCount = int(raw_input('Enter number of players: '))")); gameSetupMethod.append( indent( "if self.playerCount < self.min: print(self.name+' is made for more than '+str(self.min)+' players. Bring some friends ;-)'); exit()")); gameSetupMethod.append( indent( "if self.playerCount > self.max: print(str(self.playerCount)+' players? Thats too much for '+self.name+'... Maximum: '+str(self.max)); exit()")); gameSetupMethod.append(indent("")); gameSetupMethod.append( indent( "for p in range(self.playerCount): name = raw_input('Enter name of player #'+str(p)+': '); self.players.append(Player(name))")); gameSetupMethod.append(indent("self.activePlayer = self.players[0]")); gameSetupMethod.append(indent("print('Game initialized '+self.status())")); gameSetupMethod.append(indent("")); gameClass.append(indent(gameSetupMethod.toString())); StringBuilder gameInitMethod = new StringBuilder(); gameInitMethod.append("def __init__(self):\n"); gameInitMethod.append(indent("self.players = []")); gameInitMethod.append(indent("# Dynamic inits")); gameInitMethod.append(indent("self.name = '" + ctx.NAME.getText() + "'\n")); gameInitMethod.append(indent("")); boolean hasRunningCond = false; for (ParseTree init : ctx.children) { if (init.getClass() == DiceGameParser.GameinitContext.class) { DiceGameParser.GameinitContext initCtx = (DiceGameParser.GameinitContext) init; if (initCtx.COND != null) { gameClass.append(indent(initCtx.accept(this))); hasRunningCond = true; } else { gameInitMethod.append(indent(init.accept(this))); } } } if (!hasRunningCond) { gameClass.append(indent("def isRunning(self): return True")); } gameClass.append(indent(gameInitMethod.toString())); StringBuilder gameLoop = new StringBuilder(); gameLoop.append("while self.isRunning():\n"); gameLoop.append(indent("\nprint(self.status())")); gameLoop.append(indent("print('\\n'+self.activePlayer.name+' ist dran.'),")); gameLoop.append(indent("")); for (ParseTree init : ctx.children) { if (init.getClass() == DiceGameParser.ActionContext.class) { DiceGameParser.ActionContext loopCtx = (DiceGameParser.ActionContext) init; gameLoop.append(indent(loopCtx.accept(this))); } } String gameLoopMethod = "def loop(self):\n" + indent(gameLoop.toString()); gameClass.append(indent(gameLoopMethod)); StringBuilder main = new StringBuilder(); main.append("\nif __name__ == '__main__':\n"); main.append(indent("game = Game()")); main.append(indent("game.setup()")); main.append(indent("game.loop()")); main.append(indent("print('\\nSpiel beendet: '+game.status())")); main.append(indent(ctx.GAMEEND.accept(this))); return imports + playerClass.toString() + diceClass.toString() + gameClass.toString() + main.toString(); }