Release v3.0
This commit is contained in:
@@ -9,6 +9,11 @@
|
||||
<attribute name="javadoc_location" value="http://www.cs.kuleuven.be/books/OOPWithJava/doc/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="lib" path="lib/antlr-runtime-4.7.1.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="http://www.antlr.org/api/Java"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
||||
<classpathentry kind="src" path="resources"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
|
@@ -25,5 +25,10 @@
|
||||
<type>2</type>
|
||||
<locationURI>PROJECT_LOC/levels</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>resources/programs</name>
|
||||
<type>2</type>
|
||||
<locationURI>PROJECT_LOC/programs</locationURI>
|
||||
</link>
|
||||
</linkedResources>
|
||||
</projectDescription>
|
||||
|
BIN
OGP1718-Worms/images/burger-poisonous.png
Normal file
BIN
OGP1718-Worms/images/burger-poisonous.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
BIN
OGP1718-Worms/lib/antlr-runtime-4.7.1.jar
Normal file
BIN
OGP1718-Worms/lib/antlr-runtime-4.7.1.jar
Normal file
Binary file not shown.
35
OGP1718-Worms/programs/program.txt
Executable file
35
OGP1718-Worms/programs/program.txt
Executable file
@@ -0,0 +1,35 @@
|
||||
// Worm that turns towards nearest worm, fires, and moves; or turns and tries to jump if no worm is in sight.
|
||||
|
||||
def updateNearestWorm: {
|
||||
delta := 0;
|
||||
nearestWorm := null;
|
||||
turnToNearest := 0;
|
||||
while delta < 6.28: {
|
||||
obj := searchobj delta;
|
||||
if (obj != null && isworm obj):
|
||||
if !sameteam obj:
|
||||
if (nearestWorm == null) || (distance obj < distance nearestWorm): {
|
||||
nearestWorm := obj;
|
||||
turnToNearest := delta;
|
||||
}
|
||||
delta := delta + 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
// main program
|
||||
|
||||
while true: {
|
||||
invoke updateNearestWorm;
|
||||
|
||||
if nearestWorm != null: {
|
||||
print nearestWorm;
|
||||
print distance nearestWorm;
|
||||
turn turnToNearest;
|
||||
fire;
|
||||
move;
|
||||
}
|
||||
else {
|
||||
turn 0.2;
|
||||
jump;
|
||||
}
|
||||
}
|
20
OGP1718-Worms/programs/program_example.txt
Executable file
20
OGP1718-Worms/programs/program_example.txt
Executable file
@@ -0,0 +1,20 @@
|
||||
def controlled_move:
|
||||
if getap self > 100.0:
|
||||
{ jump;
|
||||
print getx self;
|
||||
print gety self; }
|
||||
else move;
|
||||
|
||||
max_distance := 10.0;
|
||||
while true: {
|
||||
w := searchobj 0.0;
|
||||
if isworm w: {
|
||||
if sameteam w:
|
||||
invoke controlled_move;
|
||||
else if distance w < max_distance:
|
||||
fire;
|
||||
else
|
||||
{ turn d;
|
||||
max_distance := max_distance + 0.1; }
|
||||
}
|
||||
}
|
3
OGP1718-Worms/programs/program_simple.txt
Executable file
3
OGP1718-Worms/programs/program_simple.txt
Executable file
@@ -0,0 +1,3 @@
|
||||
turn 0.2;
|
||||
fire;
|
||||
move;
|
54
OGP1718-Worms/programs/syntax_test.txt
Executable file
54
OGP1718-Worms/programs/syntax_test.txt
Executable file
@@ -0,0 +1,54 @@
|
||||
// don't execute this :-)
|
||||
def test_proc: {
|
||||
x := +1;
|
||||
while true:
|
||||
print false;
|
||||
if x == 1: {
|
||||
print x * x;
|
||||
} else: {}
|
||||
invoke test_proc;
|
||||
break;
|
||||
if 0-x/y*z - y * z - 2*x + 3 == 2 && true != false: {}
|
||||
move;
|
||||
jump;
|
||||
eat;
|
||||
fire;
|
||||
}
|
||||
|
||||
def secondProc: {
|
||||
invoke test_proc;
|
||||
if getx self > 0:
|
||||
invoke secondProc;
|
||||
}
|
||||
|
||||
x := ( 3 * 4 ); // comment
|
||||
// comment
|
||||
y := (-33.5 * (+55 / 1.22));
|
||||
|
||||
jump;
|
||||
turn 5;
|
||||
turn 0.2;
|
||||
turn -0.2;
|
||||
fire;
|
||||
|
||||
if (x >= 5):
|
||||
{ }
|
||||
else
|
||||
fire;
|
||||
|
||||
while y:
|
||||
{ turn (0.01);
|
||||
y := (y - 1); }
|
||||
|
||||
while y:
|
||||
{ move;
|
||||
y := (y - 1);
|
||||
if (true): { turn y; }
|
||||
else {
|
||||
while (false):
|
||||
{print y;}
|
||||
}
|
||||
}
|
||||
|
||||
if (true): { } else { invoke test_proc; }
|
||||
|
3
OGP1718-Worms/src-provided/worms/Worms.java
Normal file → Executable file
3
OGP1718-Worms/src-provided/worms/Worms.java
Normal file → Executable file
@@ -22,6 +22,9 @@ public class Worms {
|
||||
options.randomSeed = randomSeed;
|
||||
} else if ("-clickselect".equals(arg)) {
|
||||
options.enableClickToSelect = true;
|
||||
} else if ("-program".equals(arg)) {
|
||||
String program = args[++i];
|
||||
options.programFile = program;
|
||||
}
|
||||
}
|
||||
|
||||
|
138
OGP1718-Worms/src-provided/worms/facade/IFacade.java
Normal file → Executable file
138
OGP1718-Worms/src-provided/worms/facade/IFacade.java
Normal file → Executable file
@@ -2,7 +2,10 @@ package worms.facade;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
|
||||
import worms.internal.gui.game.IActionHandler;
|
||||
import worms.model.*;
|
||||
import worms.programs.IProgramFactory;
|
||||
import worms.util.ModelException;
|
||||
import worms.util.MustNotImplementException;
|
||||
|
||||
@@ -356,6 +359,7 @@ public interface IFacade {
|
||||
default void fall(Worm worm) throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the time needed by the given worm to jump to the nearest position
|
||||
* adjacent to impassable terrain.
|
||||
@@ -380,7 +384,17 @@ public interface IFacade {
|
||||
*/
|
||||
void jump(Worm worm, double timeStep) throws ModelException;
|
||||
|
||||
/**
|
||||
* Make the given worm eat a portion of food.
|
||||
*/
|
||||
void eat(Worm worm) throws ModelException;
|
||||
|
||||
/**
|
||||
* Have the give worm fire a projectile.
|
||||
* - The method must return the projectile that has been fired.
|
||||
*/
|
||||
Projectile fire(Worm worm) throws ModelException;
|
||||
|
||||
|
||||
/************
|
||||
* FOOD
|
||||
@@ -426,11 +440,76 @@ public interface IFacade {
|
||||
*/
|
||||
World getWorld(Food food) throws ModelException;
|
||||
|
||||
/**
|
||||
* Return whether or not the given portion of food is poisonous.
|
||||
*/
|
||||
boolean isPoisonous(Food food) throws ModelException;
|
||||
|
||||
/**
|
||||
* Poison the given portion of food.
|
||||
*/
|
||||
void poison(Food food) throws ModelException;
|
||||
|
||||
|
||||
|
||||
/*************
|
||||
* PROJECTILE
|
||||
*************/
|
||||
|
||||
/**
|
||||
* Make the given worm eat a portion of food.
|
||||
* Check whether the given projectile is terminated.
|
||||
*/
|
||||
public void eat(Worm worm);
|
||||
boolean isTerminated(Projectile projectile) throws ModelException;
|
||||
|
||||
/**
|
||||
* Return the current orientation of the given projectile (in radians).
|
||||
*/
|
||||
double getOrientation(Projectile projectile) throws ModelException;
|
||||
|
||||
/**
|
||||
* Return the current location of the given projectile.
|
||||
* - The resulting array contains the the x-coordinate of the given projectile
|
||||
* followed by its y-coordinate.
|
||||
*/
|
||||
double[] getLocation(Projectile projectile) throws ModelException;
|
||||
|
||||
/**
|
||||
* Return the radius of the given projectile.
|
||||
*/
|
||||
double getRadius(Projectile projectile);
|
||||
|
||||
/**
|
||||
* Return the number of hit points of the given projectile.
|
||||
*/
|
||||
int getNbHitPoints(Projectile projectile) throws ModelException;
|
||||
|
||||
/**
|
||||
* Returns the location on the jump trajectory of the given projectile
|
||||
* after a time t.
|
||||
* - The resulting location is an array with two elements,
|
||||
* with the first element being the x-coordinate and the
|
||||
* second element the y-coordinate.
|
||||
*/
|
||||
double[] getJumpStep(Projectile projectile, double elapsedTime);
|
||||
|
||||
/**
|
||||
* Return the time needed by the given projectile to jump to the nearest
|
||||
* location at which the projectile hits impassable terrain or a worm.
|
||||
* - deltaT determines the resolution to be used in successive steps of the jump.
|
||||
*/
|
||||
double getJumpTime(Projectile projectile, double jumpTimeStep) throws ModelException;
|
||||
|
||||
/**
|
||||
* Make the given projectile jump using the given time step.
|
||||
* - The given time step determines a time interval during which
|
||||
* you may assume that the projectile will not hit impassable
|
||||
* terrain nor a worm.
|
||||
*/
|
||||
void jump(Projectile projectile, double jumpTimeStep) throws ModelException;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/********
|
||||
* TEAM
|
||||
@@ -523,4 +602,59 @@ public interface IFacade {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**********
|
||||
* PROGRAMS
|
||||
**********/
|
||||
|
||||
/**
|
||||
* Return the program loaded on the given worm.
|
||||
*/
|
||||
Program getWormProgram(Worm worm) throws ModelException;
|
||||
|
||||
/**
|
||||
* Load the given program on the given worm.
|
||||
*
|
||||
* While executing the program, the worm must invoke the methods corresponding
|
||||
* to actions through the provided ActionHandler object (e.g., actionHandler.jump(this),
|
||||
* actionHandler.turn(this, 0.2), etc.) rather than invoking them directly (e.g., this.jump()).
|
||||
* This executes the action as if a human player has initiated it, so the GUI can update itself.
|
||||
* The GUI will also invoke the corresponding method on the worm through the facade.
|
||||
*/
|
||||
public void loadProgramOnWorm(Worm worm, Program program, IActionHandler actionHandler) throws ModelException;
|
||||
|
||||
/**
|
||||
* Execute the program loaded on the given worm.
|
||||
* The worm is positioned in some world. Returns null if the program
|
||||
* is not completely executed. Otherwise, returns the objects that have been
|
||||
* printed.
|
||||
*
|
||||
* This method is only used in the tests. The GUI never calls this method;
|
||||
* you should execute the program when the worm is activated.
|
||||
*/
|
||||
public List<Object> executeProgram(Worm worm) throws ModelException;
|
||||
|
||||
/**
|
||||
* Creates a new program factory.
|
||||
*/
|
||||
public IProgramFactory<?, ?, ?, ? extends Program> createProgramFactory() throws ModelException;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*********
|
||||
* WIZARD
|
||||
*********/
|
||||
|
||||
/**
|
||||
* Have the wizard cast a spell over two randomly slected game objects in the given
|
||||
* world.
|
||||
*/
|
||||
void castSpell(World world) throws ModelException;
|
||||
|
||||
|
||||
}
|
||||
|
0
OGP1718-Worms/src-provided/worms/internal/gui/AbstractPainter.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/AbstractPainter.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/ErrorScreen.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/ErrorScreen.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/GUIConstants.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/GUIConstants.java
Normal file → Executable file
7
OGP1718-Worms/src-provided/worms/internal/gui/GUIOptions.java
Normal file → Executable file
7
OGP1718-Worms/src-provided/worms/internal/gui/GUIOptions.java
Normal file → Executable file
@@ -26,4 +26,11 @@ public class GUIOptions {
|
||||
*/
|
||||
public boolean enableClickToSelect = false;
|
||||
|
||||
/**
|
||||
* The program that is executed by computer-controlled worms.
|
||||
* Default: "programs/program.txt"
|
||||
*
|
||||
* Can also be set from the command line with the -program argument
|
||||
*/
|
||||
public String programFile = "programs/program.txt";
|
||||
}
|
0
OGP1718-Worms/src-provided/worms/internal/gui/GUIUtils.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/GUIUtils.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/GameState.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/GameState.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/InputMode.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/InputMode.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/Level.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/Level.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/Screen.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/Screen.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/WormsGUI.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/WormsGUI.java
Normal file → Executable file
20
OGP1718-Worms/src-provided/worms/internal/gui/game/DefaultActionHandler.java
Normal file → Executable file
20
OGP1718-Worms/src-provided/worms/internal/gui/game/DefaultActionHandler.java
Normal file → Executable file
@@ -5,11 +5,13 @@ import java.util.concurrent.Executors;
|
||||
|
||||
import worms.facade.IFacade;
|
||||
import worms.internal.gui.GameState;
|
||||
import worms.internal.gui.game.commands.ActivateWizard;
|
||||
import worms.internal.gui.game.commands.AddNewFood;
|
||||
import worms.internal.gui.game.commands.AddNewTeam;
|
||||
import worms.internal.gui.game.commands.AddNewWorm;
|
||||
import worms.internal.gui.game.commands.Command;
|
||||
import worms.internal.gui.game.commands.Eat;
|
||||
import worms.internal.gui.game.commands.Fire;
|
||||
import worms.internal.gui.game.commands.Jump;
|
||||
import worms.internal.gui.game.commands.Move;
|
||||
import worms.internal.gui.game.commands.Rename;
|
||||
@@ -88,8 +90,14 @@ class DefaultActionHandler implements IActionHandler {
|
||||
executeCommand(new Rename(getFacade(), worm, newName, getScreen()));
|
||||
}
|
||||
|
||||
public void eat(Worm worm) {
|
||||
executeCommand(new Eat(getFacade(), worm, getScreen()));
|
||||
@Override
|
||||
public boolean eat(Worm worm) {
|
||||
return executeCommand(new Eat(getFacade(), worm, getScreen()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Worm worm) {
|
||||
return executeCommand(new Fire(getFacade(), worm, getScreen()));
|
||||
}
|
||||
|
||||
public void selectNextWorm() {
|
||||
@@ -100,8 +108,8 @@ class DefaultActionHandler implements IActionHandler {
|
||||
executeCommand(new StartGame(getFacade(), getScreen()));
|
||||
}
|
||||
|
||||
public void addNewWorm() {
|
||||
executeCommand(new AddNewWorm(getFacade(), getScreen()));
|
||||
public void addNewWorm(boolean withProgram) {
|
||||
executeCommand(new AddNewWorm(getFacade(), withProgram, getScreen()));
|
||||
}
|
||||
|
||||
public void addEmptyTeam(String name) {
|
||||
@@ -111,5 +119,9 @@ class DefaultActionHandler implements IActionHandler {
|
||||
public void addNewFood() {
|
||||
executeCommand(new AddNewFood(getFacade(), getScreen()));
|
||||
}
|
||||
|
||||
public void activateWizard() {
|
||||
executeCommand(new ActivateWizard(getFacade(), getScreen()));
|
||||
}
|
||||
|
||||
}
|
||||
|
5
OGP1718-Worms/src-provided/worms/internal/gui/game/IActionHandler.java
Normal file → Executable file
5
OGP1718-Worms/src-provided/worms/internal/gui/game/IActionHandler.java
Normal file → Executable file
@@ -14,6 +14,7 @@ import worms.model.Worm;
|
||||
* <li>shows periodic updates on the GUI (such as jump animations)
|
||||
* <li>eventually calls the corresponding facade methods, exactly like what
|
||||
* happens with a human player
|
||||
* <li>makes sure a worm will fall after moving
|
||||
* <li>returns true if the action has been completed successfully; false
|
||||
* otherwise
|
||||
* </ul>
|
||||
@@ -29,6 +30,10 @@ public interface IActionHandler {
|
||||
public boolean move(Worm worm);
|
||||
|
||||
public boolean jump(Worm worm);
|
||||
|
||||
public boolean eat(Worm worm);
|
||||
|
||||
public boolean fire(Worm worm);
|
||||
|
||||
/**
|
||||
* Print a message on the screen for a short amount of time.
|
||||
|
0
OGP1718-Worms/src-provided/worms/internal/gui/game/ImageSprite.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/ImageSprite.java
Normal file → Executable file
18
OGP1718-Worms/src-provided/worms/internal/gui/game/PlayGameScreen.java
Normal file → Executable file
18
OGP1718-Worms/src-provided/worms/internal/gui/game/PlayGameScreen.java
Normal file → Executable file
@@ -224,6 +224,14 @@ public class PlayGameScreen extends Screen {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void fire() {
|
||||
Worm worm = getSelectedWorm();
|
||||
if (worm != null) {
|
||||
userActionHandler.fire(worm);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void turn(double angle) {
|
||||
Worm worm = getSelectedWorm();
|
||||
@@ -397,7 +405,11 @@ public class PlayGameScreen extends Screen {
|
||||
}
|
||||
|
||||
public void addPlayerControlledWorm() {
|
||||
userActionHandler.addNewWorm();
|
||||
userActionHandler.addNewWorm(false);
|
||||
}
|
||||
|
||||
public void addComputerControlledWorm() {
|
||||
userActionHandler.addNewWorm(true);
|
||||
}
|
||||
|
||||
public void addFood() {
|
||||
@@ -445,4 +457,8 @@ public class PlayGameScreen extends Screen {
|
||||
return programActionHandler;
|
||||
}
|
||||
|
||||
public void activateWizard() {
|
||||
userActionHandler.activateWizard();
|
||||
}
|
||||
|
||||
}
|
||||
|
0
OGP1718-Worms/src-provided/worms/internal/gui/game/PlayGameScreenDebugPainter.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/PlayGameScreenDebugPainter.java
Normal file → Executable file
10
OGP1718-Worms/src-provided/worms/internal/gui/game/PlayGameScreenPainter.java
Normal file → Executable file
10
OGP1718-Worms/src-provided/worms/internal/gui/game/PlayGameScreenPainter.java
Normal file → Executable file
@@ -17,6 +17,7 @@ import worms.internal.gui.GUIUtils;
|
||||
import worms.internal.gui.GameState;
|
||||
import worms.internal.gui.Level;
|
||||
import worms.internal.gui.game.sprites.FoodSprite;
|
||||
import worms.internal.gui.game.sprites.ProjectileSprite;
|
||||
import worms.internal.gui.game.sprites.WormSprite;
|
||||
import worms.model.World;
|
||||
import worms.util.ModelException;
|
||||
@@ -102,9 +103,18 @@ public class PlayGameScreenPainter extends AbstractPainter<PlayGameScreen> {
|
||||
paintWorm(sprite);
|
||||
}
|
||||
|
||||
for (ProjectileSprite sprite : getScreen().getSpritesOfType(
|
||||
ProjectileSprite.class)) {
|
||||
paintProjectile(sprite);
|
||||
}
|
||||
|
||||
this.currentGraphics = null;
|
||||
}
|
||||
|
||||
protected void paintProjectile(ProjectileSprite sprite) {
|
||||
sprite.draw(currentGraphics);
|
||||
}
|
||||
|
||||
protected void paintFood(FoodSprite sprite) {
|
||||
sprite.draw(currentGraphics);
|
||||
}
|
||||
|
0
OGP1718-Worms/src-provided/worms/internal/gui/game/Sprite.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/Sprite.java
Normal file → Executable file
@@ -0,0 +1,29 @@
|
||||
package worms.internal.gui.game.commands;
|
||||
|
||||
import worms.facade.IFacade;
|
||||
import worms.internal.gui.game.PlayGameScreen;
|
||||
import worms.internal.gui.messages.MessageType;
|
||||
import worms.util.ModelException;
|
||||
|
||||
public class ActivateWizard extends InstantaneousCommand {
|
||||
|
||||
public ActivateWizard(IFacade facade,
|
||||
PlayGameScreen screen) {
|
||||
super(facade, screen);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canStart() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStartExecution() {
|
||||
try {
|
||||
getFacade().castSpell(getWorld());
|
||||
getScreen().addMessage("The wizard has done wizardry things!", MessageType.INFO);
|
||||
} catch (ModelException e) {
|
||||
getScreen().addMessage("The wizard could not cast its spell :(", MessageType.ERROR);
|
||||
}
|
||||
}
|
||||
}
|
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/AddNewFood.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/AddNewFood.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/AddNewTeam.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/AddNewTeam.java
Normal file → Executable file
93
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/AddNewWorm.java
Normal file → Executable file
93
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/AddNewWorm.java
Normal file → Executable file
@@ -1,21 +1,34 @@
|
||||
package worms.internal.gui.game.commands;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import worms.facade.IFacade;
|
||||
import worms.internal.gui.GUIUtils;
|
||||
import worms.internal.gui.WormsGUI;
|
||||
import worms.internal.gui.game.PlayGameScreen;
|
||||
import worms.internal.gui.messages.MessageType;
|
||||
import worms.model.Program;
|
||||
import worms.model.Team;
|
||||
import worms.model.Worm;
|
||||
import worms.programs.IProgramFactory;
|
||||
import worms.programs.ParseOutcome;
|
||||
import worms.programs.ProgramParser;
|
||||
import worms.util.ModelException;
|
||||
|
||||
public class AddNewWorm extends InstantaneousCommand {
|
||||
|
||||
private static final double MIN_RADIUS = 0.25;
|
||||
private static final double MAX_RADIUS = Math.pow(2, 1.0/3.0) * MIN_RADIUS;
|
||||
|
||||
public AddNewWorm(IFacade facade, PlayGameScreen screen) {
|
||||
private static final double MAX_RADIUS = Math.pow(2, 1.0 / 3.0) * MIN_RADIUS;
|
||||
private boolean withProgram;
|
||||
|
||||
public AddNewWorm(IFacade facade, boolean withProgram, PlayGameScreen screen) {
|
||||
super(facade, screen);
|
||||
this.withProgram = withProgram;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -36,10 +49,82 @@ public class AddNewWorm extends InstantaneousCommand {
|
||||
|
||||
double direction = random.nextDouble() * 2 * Math.PI;
|
||||
Team team = getScreen().getLastCreatedTeam();
|
||||
getFacade().createWorm(getWorld(), p, direction, radius, name, team);
|
||||
Worm worm = getFacade().createWorm(getWorld(), p, direction, radius, name, team);
|
||||
|
||||
if (withProgram) {
|
||||
loadProgram(worm);
|
||||
}
|
||||
|
||||
} catch (ModelException e) {
|
||||
e.printStackTrace();
|
||||
getScreen().addMessage("Could not create worm", MessageType.ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadProgram(Worm worm) {
|
||||
String programText = readProgramText();
|
||||
if (programText != null) {
|
||||
IProgramFactory<?, ?, ?, ? extends Program> factory = getFacade().createProgramFactory();
|
||||
ProgramParser<?, ?, ?, ? extends Program> parser = ProgramParser.create(factory);
|
||||
ParseOutcome<? extends Program> outcome = parser.parseString(programText);
|
||||
|
||||
if (outcome != null) {
|
||||
if (outcome.isSuccess()) {
|
||||
Program program = outcome.getSuccessValue();
|
||||
getFacade().loadProgramOnWorm(worm, program, getScreen().getProgramActionHandler());
|
||||
} else {
|
||||
List<String> errors = outcome.getFailValue();
|
||||
String msg = "Parsing failed\nwith the following errors:\n";
|
||||
for (String error : errors) {
|
||||
msg += error + "\n";
|
||||
}
|
||||
cancelExecution();
|
||||
getGUI().showError(msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cancelExecution();
|
||||
getGUI().showError("Could not parse program");
|
||||
}
|
||||
}
|
||||
|
||||
private WormsGUI getGUI() {
|
||||
return getScreen().getGUI();
|
||||
}
|
||||
|
||||
protected String readProgramText() {
|
||||
InputStream stream;
|
||||
try {
|
||||
stream = GUIUtils.openResource(getGUI().getOptions().programFile);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
getGUI().showError(e.getMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
|
||||
StringBuilder programText = new StringBuilder();
|
||||
String line;
|
||||
try {
|
||||
line = reader.readLine();
|
||||
while (line != null) {
|
||||
programText.append(line);
|
||||
programText.append("\n");
|
||||
line = reader.readLine();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
cancelExecution(e);
|
||||
return null;
|
||||
} finally {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
// I don't care
|
||||
}
|
||||
}
|
||||
return programText.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/Command.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/Command.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/Eat.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/Eat.java
Normal file → Executable file
83
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/Fire.java
Executable file
83
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/Fire.java
Executable file
@@ -0,0 +1,83 @@
|
||||
package worms.internal.gui.game.commands;
|
||||
|
||||
import worms.facade.IFacade;
|
||||
import worms.internal.gui.GUIConstants;
|
||||
import worms.internal.gui.game.PlayGameScreen;
|
||||
import worms.internal.gui.game.sprites.ProjectileSprite;
|
||||
import worms.internal.gui.messages.MessageType;
|
||||
import worms.model.Projectile;
|
||||
import worms.model.Worm;
|
||||
import worms.util.ModelException;
|
||||
|
||||
public class Fire extends Command {
|
||||
private final Worm worm;
|
||||
|
||||
private Projectile projectile;
|
||||
private double totalDuration;
|
||||
private boolean hasJumped;
|
||||
|
||||
public Fire(IFacade facade, Worm worm, PlayGameScreen screen) {
|
||||
super(facade, screen);
|
||||
this.worm = worm;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canStart() {
|
||||
return worm != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStartExecution() {
|
||||
try {
|
||||
projectile = getFacade().fire(worm);
|
||||
if (projectile != null) {
|
||||
totalDuration = getFacade().getJumpTime(projectile, GUIConstants.JUMP_TIME_STEP);
|
||||
ProjectileSprite sprite = new ProjectileSprite(getScreen(), projectile);
|
||||
sprite.update();
|
||||
getScreen().addSprite(sprite);
|
||||
} else {
|
||||
cancelExecution();
|
||||
}
|
||||
} catch (ModelException e) {
|
||||
e.printStackTrace();
|
||||
cancelExecution();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterExecutionCompleted() {
|
||||
super.afterExecutionCompleted();
|
||||
ProjectileSprite sprite = getScreen().getSpriteOfTypeFor(ProjectileSprite.class, projectile);
|
||||
if (sprite != null) {
|
||||
sprite.setDoneMoving();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void afterExecutionCancelled(Throwable e) {
|
||||
getScreen().addMessage("This worm cannot shoot :(" + (e != null ? "\n" + e.getMessage() : ""),
|
||||
MessageType.ERROR);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doUpdate(double dt) {
|
||||
try {
|
||||
if (getElapsedTime() >= totalDuration) {
|
||||
if (!hasJumped) {
|
||||
hasJumped = true;
|
||||
getFacade().jump(projectile, GUIConstants.JUMP_TIME_STEP);
|
||||
completeExecution();
|
||||
}
|
||||
} else {
|
||||
ProjectileSprite sprite = getScreen().getSpriteOfTypeFor(ProjectileSprite.class, projectile);
|
||||
|
||||
double[] xy = getFacade().getJumpStep(projectile, getElapsedTime());
|
||||
|
||||
sprite.setCenterLocation(getScreen().getScreenX(xy[0]), getScreen().getScreenY(xy[1]));
|
||||
}
|
||||
} catch (ModelException e) {
|
||||
e.printStackTrace();
|
||||
cancelExecution();
|
||||
}
|
||||
}
|
||||
}
|
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/InstantaneousCommand.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/InstantaneousCommand.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/Jump.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/Jump.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/Move.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/Move.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/Rename.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/Rename.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/SelectNextWorm.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/SelectNextWorm.java
Normal file → Executable file
1
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/StartGame.java
Normal file → Executable file
1
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/StartGame.java
Normal file → Executable file
@@ -24,6 +24,7 @@ public class StartGame extends InstantaneousCommand {
|
||||
protected void afterExecutionCancelled(Throwable e) {
|
||||
if (e != null) {
|
||||
getScreen().addMessage("Cannot start the game: " + e.getMessage(), MessageType.ERROR);
|
||||
e.printStackTrace();
|
||||
} else {
|
||||
getScreen().addMessage("Cannot start the game without worms", MessageType.ERROR);
|
||||
}
|
||||
|
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/Turn.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/commands/Turn.java
Normal file → Executable file
8
OGP1718-Worms/src-provided/worms/internal/gui/game/modes/DefaultInputMode.java
Normal file → Executable file
8
OGP1718-Worms/src-provided/worms/internal/gui/game/modes/DefaultInputMode.java
Normal file → Executable file
@@ -55,6 +55,14 @@ public class DefaultInputMode extends InputMode<PlayGameScreen> {
|
||||
case 'E':
|
||||
getScreen().eat();
|
||||
break;
|
||||
case 'f':
|
||||
case 'F':
|
||||
getScreen().fire();
|
||||
break;
|
||||
case 's':
|
||||
case 'S':
|
||||
getScreen().activateWizard();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
0
OGP1718-Worms/src-provided/worms/internal/gui/game/modes/EnteringNameMode.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/modes/EnteringNameMode.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/modes/GameOverMode.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/modes/GameOverMode.java
Normal file → Executable file
11
OGP1718-Worms/src-provided/worms/internal/gui/game/modes/SetupInputMode.java
Normal file → Executable file
11
OGP1718-Worms/src-provided/worms/internal/gui/game/modes/SetupInputMode.java
Normal file → Executable file
@@ -24,6 +24,10 @@ public class SetupInputMode extends InputMode<PlayGameScreen> {
|
||||
case 'W':
|
||||
getScreen().addPlayerControlledWorm();
|
||||
break;
|
||||
case 'c':
|
||||
case 'C':
|
||||
getScreen().addComputerControlledWorm();
|
||||
break;
|
||||
case 'f':
|
||||
case 'F':
|
||||
getScreen().addFood();
|
||||
@@ -49,7 +53,12 @@ public class SetupInputMode extends InputMode<PlayGameScreen> {
|
||||
getScreen()
|
||||
.showInstructions(
|
||||
g,
|
||||
"Press\n'T' to create a new team\n'W' to add a new worm\n'F' to add food\n'S' to start the game");
|
||||
"Press\n"
|
||||
+ "'T' to create a new team\n"
|
||||
+ "'W' to add a new player-controlled worm\n"
|
||||
+ "'C' to add a new computer-controlled worm\n"
|
||||
+ "'F' to add food\n"
|
||||
+ "'S' to start the game");
|
||||
}
|
||||
|
||||
}
|
||||
|
0
OGP1718-Worms/src-provided/worms/internal/gui/game/modes/TurningMode.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/modes/TurningMode.java
Normal file → Executable file
61
OGP1718-Worms/src-provided/worms/internal/gui/game/sprites/FoodSprite.java
Normal file → Executable file
61
OGP1718-Worms/src-provided/worms/internal/gui/game/sprites/FoodSprite.java
Normal file → Executable file
@@ -1,5 +1,8 @@
|
||||
package worms.internal.gui.game.sprites;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import worms.internal.gui.game.ImageSprite;
|
||||
import worms.internal.gui.game.PlayGameScreen;
|
||||
import worms.model.Food;
|
||||
@@ -12,10 +15,22 @@ public class FoodSprite extends ImageSprite<Food> {
|
||||
private final Food food;
|
||||
|
||||
private double radius;
|
||||
|
||||
private boolean poisonous = false;
|
||||
|
||||
// original image, at original scale
|
||||
private final BufferedImage originalPoisonousImage;
|
||||
|
||||
// only created when scale != 1.0
|
||||
private BufferedImage scaledPoisonousImage;
|
||||
|
||||
public FoodSprite(PlayGameScreen screen, Food food) {
|
||||
super(screen, "images/burger.png");
|
||||
this.food = food;
|
||||
// constraint: must have same dimensions as original image
|
||||
// constraint: does not respect hflipping
|
||||
this.originalPoisonousImage = loadImage("images/burger-poisonous.png");
|
||||
this.scaledPoisonousImage = this.originalPoisonousImage;
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -45,9 +60,52 @@ public class FoodSprite extends ImageSprite<Food> {
|
||||
|
||||
setScale(scaleFactor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScale(double newScale) {
|
||||
double oldScale = getScale();
|
||||
|
||||
super.setScale(newScale);
|
||||
|
||||
if (newScale == oldScale) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (newScale != 1.0) {
|
||||
this.scaledPoisonousImage = toBufferedImage(originalPoisonousImage.getScaledInstance(
|
||||
(int) (newScale * originalPoisonousImage.getWidth()),
|
||||
(int) (newScale * originalPoisonousImage.getHeight()),
|
||||
Image.SCALE_SMOOTH));
|
||||
} else {
|
||||
this.scaledPoisonousImage = originalPoisonousImage;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Image getImageToDraw() {
|
||||
if (isPoisonous()) {
|
||||
return scaledPoisonousImage;
|
||||
} else {
|
||||
return super.getImageToDraw();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized double getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
public synchronized boolean isPoisonous() {
|
||||
return poisonous;
|
||||
}
|
||||
|
||||
public void setPoisonous(boolean poisonous) {
|
||||
this.poisonous = poisonous;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void update() {
|
||||
setPoisonous(getFacade().isPoisonous(getFood()));
|
||||
setRadius(getFacade().getRadius(getFood()));
|
||||
double[] xy = getFacade().getLocation(getFood());
|
||||
setCenterLocation(getScreen().getScreenX(xy[0]), getScreen().getScreenY(xy[1]));
|
||||
@@ -67,8 +125,5 @@ public class FoodSprite extends ImageSprite<Food> {
|
||||
return !getFacade().isTerminated(food);
|
||||
}
|
||||
|
||||
public synchronized double getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
}
|
||||
|
143
OGP1718-Worms/src-provided/worms/internal/gui/game/sprites/ProjectileSprite.java
Executable file
143
OGP1718-Worms/src-provided/worms/internal/gui/game/sprites/ProjectileSprite.java
Executable file
@@ -0,0 +1,143 @@
|
||||
package worms.internal.gui.game.sprites;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import worms.internal.gui.GUIUtils;
|
||||
import worms.internal.gui.game.PlayGameScreen;
|
||||
import worms.internal.gui.game.Sprite;
|
||||
import worms.model.Projectile;
|
||||
|
||||
public class ProjectileSprite extends Sprite<Projectile> {
|
||||
|
||||
private static final int MIN_DISPLAY_SIZE = 3; // pixels
|
||||
private static final int MAX_DISPLAY_SIZE = 10; // pixels
|
||||
private static final int DISPLAY_SCALE = 10;
|
||||
|
||||
private static final int NB_HISTORY = 15;
|
||||
private static final Color[] colors = new Color[NB_HISTORY];
|
||||
static {
|
||||
for (int i = 0; i < colors.length; i++) {
|
||||
float t = (float) i / colors.length;
|
||||
colors[i] = new Color(1.0F, (1 - t), 0, 0.8F);
|
||||
}
|
||||
}
|
||||
|
||||
private final Projectile projectile;
|
||||
|
||||
private double sizeInPixels;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private static class LimitedQueue<E> extends LinkedList<E> {
|
||||
private int limit;
|
||||
|
||||
public LimitedQueue(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(E o) {
|
||||
boolean result = super.add(o);
|
||||
while (size() > limit) {
|
||||
super.remove();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private final List<double[]> lastLocations = Collections.synchronizedList(new LimitedQueue<double[]>(
|
||||
NB_HISTORY));
|
||||
private boolean moving;
|
||||
|
||||
public ProjectileSprite(PlayGameScreen screen, Projectile projectile) {
|
||||
super(screen);
|
||||
this.projectile = projectile;
|
||||
this.moving = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void draw(Graphics2D g) {
|
||||
if (moving) {
|
||||
for (int i = 0; i < lastLocations.size(); i++) {
|
||||
double[] loc = lastLocations.get(i);
|
||||
g.setColor(colors[i]);
|
||||
double t = (double) (i + 1) / lastLocations.size();
|
||||
double size = sizeInPixels * t * t * t;
|
||||
g.fill(GUIUtils.circleAt(loc[0], loc[1], size));
|
||||
}
|
||||
} else {
|
||||
g.setColor(colors[NB_HISTORY-1]);
|
||||
g.fill(GUIUtils.circleAt(getCenterX(), getCenterY(), sizeInPixels));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Projectile getObject() {
|
||||
return getProjectile();
|
||||
}
|
||||
|
||||
public Projectile getProjectile() {
|
||||
return projectile;
|
||||
}
|
||||
|
||||
public synchronized void setSize(double sizeInPixels) {
|
||||
this.sizeInPixels = Math.min(MAX_DISPLAY_SIZE,
|
||||
Math.max(MIN_DISPLAY_SIZE, DISPLAY_SCALE * sizeInPixels));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getHeight(Graphics2D g) {
|
||||
return sizeInPixels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getWidth(Graphics2D g) {
|
||||
return sizeInPixels;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isObjectAlive() {
|
||||
return !getFacade().isTerminated(getProjectile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void update() {
|
||||
setSize(getScreen().worldToScreenDistance(getFacade().getRadius(getProjectile())));
|
||||
double[] loc = getFacade().getLocation(getProjectile());
|
||||
setCenterLocation(getScreen().getScreenX(loc[0]), getScreen().getScreenY(loc[1]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setCenterLocation(double x, double y) {
|
||||
super.setCenterLocation(x, y);
|
||||
if (moving && !lastLocations.isEmpty()) {
|
||||
// do some averaving to show some intermediate positions for
|
||||
// fast-moving object (rifle projectiles)
|
||||
|
||||
if (lastLocations.size() > 1) {
|
||||
double[] c1 = lastLocations.get(lastLocations.size() - 1);
|
||||
double[] c2 = lastLocations.get(0);
|
||||
lastLocations.add(new double[] { (c1[0] + c2[0]) / 2,
|
||||
(c1[1] + c2[1]) / 2 });
|
||||
}
|
||||
double[] prev = lastLocations.get(lastLocations.size() - 1);
|
||||
lastLocations.remove(prev);
|
||||
|
||||
for (int i = 0; i < NB_HISTORY; i++) {
|
||||
if (prev != null) {
|
||||
double t = (double) i / (NB_HISTORY);
|
||||
lastLocations.add(new double[] { t * x + (1 - t) * prev[0],
|
||||
t * y + (1 - t) * prev[1] });
|
||||
}
|
||||
}
|
||||
}
|
||||
lastLocations.add(new double[] { x, y });
|
||||
}
|
||||
|
||||
public synchronized void setDoneMoving() {
|
||||
this.moving = false;
|
||||
}
|
||||
}
|
0
OGP1718-Worms/src-provided/worms/internal/gui/game/sprites/WormSprite.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/game/sprites/WormSprite.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/menu/AbstractMenuScreen.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/menu/AbstractMenuScreen.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/menu/ChooseLevelScreen.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/menu/ChooseLevelScreen.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/menu/MainMenuScreen.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/menu/MainMenuScreen.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/menu/MenuInputMode.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/menu/MenuInputMode.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/messages/Message.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/messages/Message.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/messages/MessageDisplay.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/messages/MessageDisplay.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/messages/MessagePainter.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/messages/MessagePainter.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/messages/MessageType.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/internal/gui/messages/MessageType.java
Normal file → Executable file
443
OGP1718-Worms/src-provided/worms/programs/IProgramFactory.java
Executable file
443
OGP1718-Worms/src-provided/worms/programs/IProgramFactory.java
Executable file
@@ -0,0 +1,443 @@
|
||||
package worms.programs;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import worms.util.ModelException;
|
||||
import worms.util.MustNotImplementException;
|
||||
|
||||
/**
|
||||
* A program factory is used by the parser ({@link ProgramParser}) to construct
|
||||
* an in-memory representation of your program. For example, when reading the
|
||||
* program source code
|
||||
*
|
||||
* <pre>
|
||||
* print 2.0
|
||||
* </pre>
|
||||
*
|
||||
* the parser will create a Program object by (conceptually) executing the
|
||||
* following code:
|
||||
*
|
||||
* <pre>
|
||||
* factory.createProgram(Collections.emptyList(),
|
||||
* factory.createPrintStatement(factory.createDoubleLiteral(2.0)));
|
||||
* </pre>
|
||||
*
|
||||
* on the returned factory object.
|
||||
*
|
||||
* <p>
|
||||
* For testing, you may use the methods from {@link ProgramParser} yourself.
|
||||
* </p>
|
||||
*
|
||||
* <p>
|
||||
* You should declare your class as follows:<code><pre>
|
||||
* public class ProgramFactory implements IProgramFactory<MyExpression, MyStatement, MyProc, Program>
|
||||
* </pre></code> where MyExpression, MyStatement, MyProc, and Program are your classes
|
||||
* for representing expressions, statements, procedure definitions, and programs,
|
||||
* respectively.
|
||||
*
|
||||
* <p>
|
||||
* The SourceLocation object in the methods defined by this factory refers to
|
||||
* the location (line and column) in the text file where the statement or
|
||||
* expression begins.
|
||||
*
|
||||
* @param <E>
|
||||
* Your class for representing an expression.
|
||||
* @param <S>
|
||||
* Your class for representing a statement.
|
||||
* @param <P>
|
||||
* Your class for representing a procedure.
|
||||
* @param <Program>
|
||||
* Your class for representing a program (should be Program).
|
||||
*
|
||||
*
|
||||
*/
|
||||
public interface IProgramFactory<E, S, P, Program> {
|
||||
|
||||
/* PROGRAM */
|
||||
|
||||
/**
|
||||
* Create a program from the given arguments.
|
||||
*
|
||||
* @param procs
|
||||
* The procedure definitions for the program.
|
||||
* @param main
|
||||
* The main statement of the program. Most likely this is a
|
||||
* sequence statement.
|
||||
* @return A new program.
|
||||
*/
|
||||
public Program createProgram(List<P> procs, S main) throws ModelException;
|
||||
|
||||
/**
|
||||
* Create a program from the given argument.
|
||||
*
|
||||
* @param main
|
||||
* The main statement of the program. Most likely this is a
|
||||
* sequence statement.
|
||||
* @return A new program without procedure definitions.
|
||||
*/
|
||||
public default Program createProgram(S main) throws ModelException {
|
||||
return createProgram(new ArrayList<P>(), main);
|
||||
}
|
||||
|
||||
/* PROCEDURE DEFINITIONS */
|
||||
|
||||
/**
|
||||
* Create a procedure definition with the given name and body.
|
||||
*
|
||||
* @param procedureName
|
||||
* The name of the procedure
|
||||
* @param body
|
||||
* The body of the procedure.
|
||||
*/
|
||||
public P createProcedureDefinition(String procedureName, S body, SourceLocation sourceLocation);
|
||||
|
||||
/* STATEMENTS */
|
||||
|
||||
/**
|
||||
* Create a statement that assigns the value obtained by evaluating the
|
||||
* given expression to a variable with the given name.
|
||||
*/
|
||||
public S createAssignmentStatement(String variableName, E value, SourceLocation sourceLocation)
|
||||
throws ModelException;
|
||||
|
||||
/**
|
||||
* Create a print statement that prints the value obtained by evaluating the
|
||||
* given expression.
|
||||
*/
|
||||
public S createPrintStatement(E value, SourceLocation sourceLocation) throws ModelException;
|
||||
|
||||
/**
|
||||
* Create a turn statement that makes the worm that is executing the program
|
||||
* turn by the amount obtained by evaluating the given expression.
|
||||
*/
|
||||
public S createTurnStatement(E angle, SourceLocation location) throws ModelException;
|
||||
|
||||
/**
|
||||
* Create a statement that makes the worm that is executing the program move
|
||||
* one step.
|
||||
*/
|
||||
public S createMoveStatement(SourceLocation location) throws ModelException;
|
||||
|
||||
/**
|
||||
* Returns a statement that makes the worm that is executing the program jump.
|
||||
*/
|
||||
public S createJumpStatement(SourceLocation location) throws ModelException;
|
||||
|
||||
/**
|
||||
* Returns a statement that makes the worm that is executing the program eat.
|
||||
*/
|
||||
public S createEatStatement(SourceLocation location);
|
||||
|
||||
/**
|
||||
* Returns a statement that makes the worm that is executing the program fire
|
||||
* a weapon.
|
||||
*/
|
||||
public S createFireStatement(SourceLocation location) throws ModelException;
|
||||
|
||||
/**
|
||||
* Create a sequence of statements involving the given list of statements.
|
||||
*/
|
||||
public S createSequenceStatement(List<S> statements, SourceLocation sourceLocation) throws ModelException;
|
||||
|
||||
/**
|
||||
* Create an if-then-else statement involving the given condition and the
|
||||
* given then-part and else-part.
|
||||
* The else-part may be null.
|
||||
*/
|
||||
public S createIfStatement(E condition, S ifBody, S elseBody, SourceLocation sourceLocation) throws ModelException;
|
||||
|
||||
/**
|
||||
* Create a while statement involving the given condition and given body.
|
||||
*/
|
||||
public S createWhileStatement(E condition, S body, SourceLocation sourceLocation) throws ModelException;
|
||||
|
||||
/**
|
||||
* Create a break statement.
|
||||
*/
|
||||
public default S createBreakStatement(SourceLocation sourceLocation)
|
||||
throws ModelException, MustNotImplementException {
|
||||
// Individual students must not work out this method.
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an invoke statement that invokes the procedure with the given name.
|
||||
*/
|
||||
public default S createInvokeStatement(String procedureName, SourceLocation sourceLocation)
|
||||
throws ModelException, MustNotImplementException {
|
||||
// Individual students must not work out this method.
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/* EXPRESSIONS */
|
||||
|
||||
/**
|
||||
* Create an expression that evaluates to the current value of the given
|
||||
* variable.
|
||||
*/
|
||||
public E createReadVariableExpression(String variableName, SourceLocation sourceLocation) throws ModelException;
|
||||
|
||||
/**
|
||||
* Creates an expression that represents a literal double value.
|
||||
*/
|
||||
public E createDoubleLiteralExpression(double value, SourceLocation location) throws ModelException;
|
||||
|
||||
/**
|
||||
* Creates an expression that represents a literal boolean value.
|
||||
*/
|
||||
public E createBooleanLiteralExpression(boolean value, SourceLocation location) throws ModelException;
|
||||
|
||||
/**
|
||||
* Creates an expression that represents the null value.
|
||||
*/
|
||||
public E createNullExpression(SourceLocation location) throws ModelException;
|
||||
|
||||
/**
|
||||
* Creates an expression that represents the self value, evaluating to the
|
||||
* worm that executes the program.
|
||||
*/
|
||||
public E createSelfExpression(SourceLocation location) throws ModelException;
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to the addition of the values
|
||||
* obtained by evaluating the given left and second expressions.
|
||||
*/
|
||||
public E createAdditionExpression(E left, E right, SourceLocation location) throws ModelException;
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to the subtraction of the values
|
||||
* obtained by evaluating the first and second given expressions.
|
||||
*/
|
||||
public default E createSubtractionExpression(E left, E right, SourceLocation location)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to the multiplication of the values
|
||||
* obtained by evaluating the first and second given expressions.
|
||||
*/
|
||||
public default E createMultiplicationExpression(E left, E right, SourceLocation location)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to the division of the values
|
||||
* obtained by evaluating the first and second given expressions.
|
||||
*/
|
||||
public default E createDivisionExpression(E left, E right, SourceLocation location)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to the square root of the value
|
||||
* obtained by evaluating the given expression.
|
||||
*/
|
||||
public default E createSqrtExpression(E e, SourceLocation location)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to the sine of the value
|
||||
* obtained by evaluating the given expression.
|
||||
*/
|
||||
public default E createSinExpression(E e, SourceLocation location)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to the cosine of the value
|
||||
* obtained by evaluating the given expression.
|
||||
*/
|
||||
public default E createCosExpression(E e, SourceLocation location)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to the conjunction of the values
|
||||
* obtained by evaluating the given left and right expressions.
|
||||
*/
|
||||
public E createAndExpression(E left, E right, SourceLocation sourceLocation) throws ModelException;
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to the disjunction of the values
|
||||
* obtained by evaluating the given left and right expressions.
|
||||
*/
|
||||
public default E createOrExpression(E left, E right, SourceLocation sourceLocation)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to true when the given expression
|
||||
* evaluates to false, and vice versa.
|
||||
*/
|
||||
public E createNotExpression(E expression, SourceLocation sourceLocation) throws ModelException;
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to true if the evaluation of the
|
||||
* left expression yields a value that is equal to the value obtained by
|
||||
* evaluating the right expression.
|
||||
*/
|
||||
public E createEqualityExpression(E left, E right, SourceLocation location) throws ModelException;
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to true if the evaluation of the
|
||||
* left expression yields a value that is different from the value obtained by
|
||||
* evaluating the right expression.
|
||||
*/
|
||||
public default E createInequalityExpression(E left, E right, SourceLocation sourceLocation)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to true if the evaluation of the
|
||||
* left expression yields a value that is less than the value obtained by
|
||||
* evaluating the right expression.
|
||||
*/
|
||||
public E createLessThanExpression(E left, E right, SourceLocation location);
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to true if the evaluation of the
|
||||
* left expression yields a value that is less than or equal to the value obtained by
|
||||
* evaluating the right expression.
|
||||
*/
|
||||
public default E createLessThanOrEqualExpression(E left, E right, SourceLocation sourceLocation)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to true if the evaluation of the
|
||||
* left expression yields a value that is greater than the value obtained by
|
||||
* evaluating the right expression.
|
||||
*/
|
||||
public default E createGreaterThanExpression(E left, E right, SourceLocation sourceLocation)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to true if the evaluation of the
|
||||
* left expression yields a value that is greater than or equal to the value obtained by
|
||||
* evaluating the right expression.
|
||||
*/
|
||||
public default E createGreaterThanOrEqualExpression(E left, E right, SourceLocation sourceLocation)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to the position along the x-axis of
|
||||
* the game object to which the given expression evaluates.
|
||||
*/
|
||||
public default E createGetXExpression(E e, SourceLocation location)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to the position along the y-axis of
|
||||
* the game object to which the given expression evaluates.
|
||||
*/
|
||||
public default E createGetYExpression(E e, SourceLocation location)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to the radius of the game object to which
|
||||
* the given expression evaluates.
|
||||
*/
|
||||
public default E createGetRadiusExpression(E e, SourceLocation location)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to the direction of the game object to which
|
||||
* the given expression evaluates.
|
||||
*/
|
||||
public default E createGetDirectionExpression(E entity, SourceLocation location)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to the number of action points of the worm to which
|
||||
* the given expression evaluates.
|
||||
*/
|
||||
public default E createGetActionPointsExpression(E entity, SourceLocation sourceLocation)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to the maximum number of action points of the worm to which
|
||||
* the given expression evaluates.
|
||||
*/
|
||||
public default E createGetMaxActionPointsExpression(E entity, SourceLocation sourceLocation)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to the number of hit points of the game object to which
|
||||
* the given expression evaluates.
|
||||
*/
|
||||
public default E createHitPointsExpression(E entity, SourceLocation sourceLocation)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
public E createSearchObjectExpression(E angleDelta, SourceLocation sourceLocation) throws ModelException;
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to a boolean reflecting whether or not
|
||||
* the executing worm belongs to the same team as the worm to which the given
|
||||
* expression evaluates.
|
||||
*/
|
||||
public default E createSameTeamExpression(E entity, SourceLocation sourceLocation)
|
||||
throws ModelException, MustNotImplementException {
|
||||
// Individual students must not work out this method.
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an expression that evaluates to the distance between the executing worm
|
||||
* and the game object to which the given expression evaluates.
|
||||
*/
|
||||
public E createDistanceExpression(E entity, SourceLocation sourceLocation) throws ModelException;
|
||||
|
||||
/**
|
||||
* Returns a boolean indicating whether or not the object to which the given
|
||||
* expression evaluates is a worm.
|
||||
*/
|
||||
public E createIsWormExpression(E entity, SourceLocation sourceLocation) throws ModelException;
|
||||
|
||||
/**
|
||||
* Returns a boolean indicating whether or not the object to which the given
|
||||
* expression evaluates is a portion of food.
|
||||
*/
|
||||
public default E createIsFoodExpression(E entity, SourceLocation sourceLocation)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a boolean indicating whether or not the object to which the given
|
||||
* expression evaluates is a projectile.
|
||||
*/
|
||||
public default E createIsProjectileExpression(E entity, SourceLocation sourceLocation)
|
||||
throws ModelException, MustNotImplementException {
|
||||
throw new MustNotImplementException();
|
||||
}
|
||||
|
||||
}
|
20
OGP1718-Worms/src-provided/worms/programs/ParseOutcome.java
Executable file
20
OGP1718-Worms/src-provided/worms/programs/ParseOutcome.java
Executable file
@@ -0,0 +1,20 @@
|
||||
package worms.programs;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import worms.programs.SuccessOrFail.WrappedSuccessOrFail;
|
||||
|
||||
public class ParseOutcome<P> extends WrappedSuccessOrFail<P, List<String>> {
|
||||
|
||||
private ParseOutcome(SuccessOrFail<P, List<String>> outcome) {
|
||||
super(outcome);
|
||||
}
|
||||
|
||||
public static <P> ParseOutcome<P> success(P p) {
|
||||
return new ParseOutcome<>(DefaultSuccessOrFail.success(p));
|
||||
}
|
||||
|
||||
public static <P> ParseOutcome<P> failure(List<String> errors) {
|
||||
return new ParseOutcome<>(DefaultSuccessOrFail.failure(errors));
|
||||
}
|
||||
}
|
245
OGP1718-Worms/src-provided/worms/programs/ProgramParser.java
Executable file
245
OGP1718-Worms/src-provided/worms/programs/ProgramParser.java
Executable file
@@ -0,0 +1,245 @@
|
||||
package worms.programs;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.antlr.v4.runtime.BaseErrorListener;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.RecognitionException;
|
||||
import org.antlr.v4.runtime.Recognizer;
|
||||
|
||||
import worms.programs.IProgramFactory;
|
||||
import worms.programs.internal.parser.ParserVisitor;
|
||||
import worms.programs.internal.parser.generated.WormsProgramLexer;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser;
|
||||
import worms.internal.gui.GUIUtils;
|
||||
import worms.model.Program;
|
||||
|
||||
/**
|
||||
* Parser for Worms programs.
|
||||
*
|
||||
* To use this class, first create an implementation of {@link IProgramFactory}:
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* IProgramFactory<MyExpression, MyStatement, MyProcedure, Program> factory = new ProgramFactory();
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* The easiest way to use this class for parsing a Program given as a String is
|
||||
* via the {@link #parseProgramFromString(String, IProgramFactory)} method:
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* Program program = ProgramParser.parseProgram(text, factory);
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* For more control, create an instance of this class:
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* ProgramParser<MyExpression, MyStatement, Task> parser = new ProgramParser<>(factory);
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* Finally, parse a string or file: <code><pre>
|
||||
* ParseOurcome<Program> parseResult = parser.parse(textToParse);
|
||||
* </pre></code>
|
||||
*
|
||||
* If parsing is successful, <code>parseResult.isSuccess()</code> returns true
|
||||
* and <code>parseResult.getSuccessValue()</code> returns the created program.
|
||||
*
|
||||
* If parsing was not successful, <code>parseResult.ifSuccess()</code> returns
|
||||
* false and <code>parseResult.getFailValue()</code> returns the list of errors
|
||||
* during parsing.
|
||||
*
|
||||
*
|
||||
* @param E
|
||||
* The type of expressions
|
||||
* @param S
|
||||
* The type of statements
|
||||
* @param P
|
||||
* The type of procedures
|
||||
* @param Prg
|
||||
* The type of program that is created; should be your
|
||||
* worms.model.Program class
|
||||
*/
|
||||
public class ProgramParser<E, S, P, Prg> {
|
||||
|
||||
private final IProgramFactory<E, S, P, Prg> factory;
|
||||
|
||||
private final List<String> errors = new ArrayList<>();
|
||||
|
||||
protected ProgramParser(IProgramFactory<E, S, P, Prg> factory) {
|
||||
if (factory == null) {
|
||||
throw new NullPointerException("Factory must be effective.");
|
||||
}
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public IProgramFactory<E, S, P, Prg> getFactory() {
|
||||
return factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the program that results from parsing the given string, or
|
||||
* Optional.empty() if parsing has failed.
|
||||
*
|
||||
* When parsing has failed, the error messages can be retrieved with the
|
||||
* getErrors() method.
|
||||
*
|
||||
*/
|
||||
public ParseOutcome<Prg> parseString(String string) {
|
||||
return parse(CharStreams.fromString(string));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the program that results from parsing the file with the given name,
|
||||
* or Optional.empty() if parsing has failed.
|
||||
*
|
||||
* When parsing has failed, the error messages can be retrieved with the
|
||||
* getErrors() method.
|
||||
*/
|
||||
public ParseOutcome<Prg> parseFile(String filename) throws IOException {
|
||||
return parse(CharStreams.fromStream(GUIUtils.openResource(filename)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the program that results from parsing the file with the given URL, or
|
||||
* Optional.empty() if parsing has failed.
|
||||
*
|
||||
* When parsing has failed, the error messages can be retrieved with the
|
||||
* getErrors() method.
|
||||
*/
|
||||
public ParseOutcome<Prg> parseFile(URL url) throws IOException {
|
||||
return parse(CharStreams.fromStream(GUIUtils.openResource(url)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the program that results from parsing the given CharStream, or
|
||||
* Optional.empty() if parsing has failed.
|
||||
*
|
||||
* When parsing has failed, the error messages can be retrieved with the
|
||||
* getErrors() method.
|
||||
*
|
||||
* @note For more convenient methods, see the
|
||||
* {@link #parseProgramFromString(String, ITaskFactory, List)},
|
||||
* {@link #parseProgramFromFile(String, ITaskFactory, List)},
|
||||
* {@link #parseString(String, List)} and {@link #parseFile(String, List)}
|
||||
* methods.
|
||||
*/
|
||||
protected ParseOutcome<Prg> parse(CharStream input) {
|
||||
reset();
|
||||
|
||||
WormsProgramLexer lexer = new WormsProgramLexer(input);
|
||||
WormsProgramParser parser = new WormsProgramParser(new CommonTokenStream(lexer));
|
||||
parser.addErrorListener(new BaseErrorListener() {
|
||||
@Override
|
||||
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line,
|
||||
int charPositionInLine, String msg, RecognitionException e) {
|
||||
errors.add(msg + " (" + line + ", " + charPositionInLine + ")");
|
||||
}
|
||||
});
|
||||
ParserVisitor<E, S, P, Prg> visitor = new ParserVisitor<>(factory);
|
||||
try {
|
||||
visitor.visitProgram(parser.program());
|
||||
if (errors.isEmpty()) {
|
||||
assert visitor.getMain() != null;
|
||||
Prg program = factory.createProgram(visitor.getProcedures(), visitor.getMain());
|
||||
if (program != null) {
|
||||
return ParseOutcome.success(program);
|
||||
}
|
||||
errors.add("Factory did not return a Program object");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
errors.add(e.toString());
|
||||
}
|
||||
return ParseOutcome.failure(errors);
|
||||
}
|
||||
|
||||
protected void reset() {
|
||||
this.errors.clear();
|
||||
}
|
||||
|
||||
public List<String> getErrors() {
|
||||
return Collections.unmodifiableList(errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new parser from the given factory.
|
||||
*
|
||||
* @param factory
|
||||
* @return
|
||||
*/
|
||||
public static <E, S, T, P> ProgramParser<E, S, T, P> create(IProgramFactory<E, S, T, P> factory) {
|
||||
return new ProgramParser<>(factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse program text using the given factory.
|
||||
*
|
||||
* @param text
|
||||
* The text to parse
|
||||
* @param factory
|
||||
* The factory to use
|
||||
* @return The parsed program, if any, or null if an error occurred during
|
||||
* parsing.
|
||||
*/
|
||||
public static Program parseProgramFromString(String text, IProgramFactory<?, ?, ?, ? extends Program> factory) {
|
||||
ProgramParser<?, ?, ?, ? extends Program> parser = create(factory);
|
||||
ParseOutcome<? extends Program> outcome = parser.parseString(text);
|
||||
if (outcome.isFail()) {
|
||||
System.out.println("Parsing failed: " + outcome.getFailValue());
|
||||
return null;
|
||||
}
|
||||
return outcome.getSuccessValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse program from a file using the given factory.
|
||||
*
|
||||
* @param filename
|
||||
* The filename from which to read the program text
|
||||
* @param factory
|
||||
* The factory to use
|
||||
* @return The parsed program, if any, or null if an error occurred during
|
||||
* parsing.
|
||||
*/
|
||||
public static Program parseProgramFromFile(String filename, IProgramFactory<?, ?, ?, ? extends Program> factory)
|
||||
throws IOException {
|
||||
ProgramParser<?, ?, ?, ? extends Program> parser = create(factory);
|
||||
ParseOutcome<? extends Program> outcome = parser.parseFile(filename);
|
||||
if (outcome.isFail()) {
|
||||
System.out.println("Parsing failed: " + outcome.getFailValue());
|
||||
return null;
|
||||
}
|
||||
return outcome.getSuccessValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse program from a file using the given factory.
|
||||
*
|
||||
* @param filename
|
||||
* The filename from which to read the program text
|
||||
* @param factory
|
||||
* The factory to use
|
||||
* @return The parsed program, if any, or null if an error occurred during
|
||||
* parsing.
|
||||
*/
|
||||
public static Program parseProgramFromURL(URL url, IProgramFactory<?, ?, ?, Program> factory) throws IOException {
|
||||
ProgramParser<?, ?, ?, Program> parser = create(factory);
|
||||
ParseOutcome<Program> outcome = parser.parseFile(url);
|
||||
if (outcome.isFail()) {
|
||||
System.out.println("Parsing failed: " + outcome.getFailValue());
|
||||
return null;
|
||||
}
|
||||
return outcome.getSuccessValue();
|
||||
}
|
||||
}
|
61
OGP1718-Worms/src-provided/worms/programs/SourceLocation.java
Executable file
61
OGP1718-Worms/src-provided/worms/programs/SourceLocation.java
Executable file
@@ -0,0 +1,61 @@
|
||||
package worms.programs;
|
||||
|
||||
import be.kuleuven.cs.som.annotate.Value;
|
||||
|
||||
/**
|
||||
* A source location represents a position in a source file,
|
||||
* denoted by the line and column (position in the line) of
|
||||
* a certain character in the file.
|
||||
*
|
||||
* This class is a value class.
|
||||
*/
|
||||
@Value
|
||||
public final class SourceLocation {
|
||||
|
||||
private final int line;
|
||||
private final int column;
|
||||
|
||||
public SourceLocation(int line, int column) {
|
||||
this.line = line;
|
||||
this.column = column;
|
||||
}
|
||||
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
public int getColumn() {
|
||||
return column;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + column;
|
||||
result = prime * result + line;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
SourceLocation other = (SourceLocation) obj;
|
||||
if (column != other.column)
|
||||
return false;
|
||||
if (line != other.line)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("@%d,%d", line, column);
|
||||
}
|
||||
|
||||
}
|
100
OGP1718-Worms/src-provided/worms/programs/SuccessOrFail.java
Executable file
100
OGP1718-Worms/src-provided/worms/programs/SuccessOrFail.java
Executable file
@@ -0,0 +1,100 @@
|
||||
package worms.programs;
|
||||
|
||||
/**
|
||||
* An interface that holds either a success value of type S or a failure value of type F.
|
||||
*/
|
||||
public interface SuccessOrFail<S, F> {
|
||||
|
||||
public boolean isSuccess();
|
||||
|
||||
public S getSuccessValue();
|
||||
|
||||
public F getFailValue();
|
||||
|
||||
public default boolean isFail() {
|
||||
return !isSuccess();
|
||||
}
|
||||
|
||||
public static class DefaultSuccessOrFail<S, F> implements SuccessOrFail<S, F> {
|
||||
private final boolean success;
|
||||
private final F failValue;
|
||||
private final S successValue;
|
||||
|
||||
private DefaultSuccessOrFail(boolean success, S successValue, F failValue) {
|
||||
if (success && failValue != null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (!success && successValue != null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
this.success = success;
|
||||
this.successValue = successValue;
|
||||
this.failValue = failValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public F getFailValue() {
|
||||
return failValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public S getSuccessValue() {
|
||||
return successValue;
|
||||
}
|
||||
|
||||
public static <S, F> SuccessOrFail<S, F> success(S successValue) {
|
||||
return new DefaultSuccessOrFail<>(true, successValue, null);
|
||||
}
|
||||
|
||||
public static <S, F> SuccessOrFail<S, F> failure(F failValue) {
|
||||
return new DefaultSuccessOrFail<>(false, null, failValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (isSuccess()) {
|
||||
return "SUCCESS value: " + getSuccessValue();
|
||||
} else {
|
||||
return "FAIL value: " + getFailValue();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class WrappedSuccessOrFail<S, F> implements SuccessOrFail<S, F> {
|
||||
private final SuccessOrFail<S, F> wrapped;
|
||||
|
||||
protected WrappedSuccessOrFail(SuccessOrFail<S, F> wrapped) {
|
||||
if (wrapped == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuccess() {
|
||||
return wrapped.isSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
public S getSuccessValue() {
|
||||
return wrapped.getSuccessValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public F getFailValue() {
|
||||
return wrapped.getFailValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return wrapped.toString();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
392
OGP1718-Worms/src-provided/worms/programs/internal/parser/ParserVisitor.java
Executable file
392
OGP1718-Worms/src-provided/worms/programs/internal/parser/ParserVisitor.java
Executable file
@@ -0,0 +1,392 @@
|
||||
package worms.programs.internal.parser;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import worms.programs.IProgramFactory;
|
||||
import worms.programs.SourceLocation;
|
||||
import worms.programs.internal.parser.generated.WormsProgramBaseVisitor;
|
||||
import worms.programs.internal.parser.generated.WormsProgramLexer;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.AddSubExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.AndOrExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.AssignmentStatementContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.BreakStatementContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.ComparisonExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.ConstantExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.CosExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.DistanceExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.EatActionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.FalseLiteralExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.FireActionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.GetAPExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.GetDirectionExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.GetHPExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.GetMaxAPExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.GetRadiusExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.GetXExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.GetYExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.IfStatementContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.InvokeStatementContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.IsFoodExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.IsProjectileExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.IsWormExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.JumpActionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.MoveActionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.MulDivExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.NotExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.NullExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.ParenExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.PrintStatementContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.ProceduredefContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.ProgramContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.ReadVariableExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.SameTeamExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.SearchObjExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.SelfExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.SequenceStatementContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.SinExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.SqrtExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.TrueLiteralExpressionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.TurnActionContext;
|
||||
import worms.programs.internal.parser.generated.WormsProgramParser.WhileStatementContext;
|
||||
|
||||
public class ParserVisitor<E, S, P, Prg> extends WormsProgramBaseVisitor<Void> {
|
||||
|
||||
@Override
|
||||
public Void visitProgram(ProgramContext ctx) {
|
||||
procedures = ctx.procdef.stream().map(procdef -> procDefVisitor.visit(procdef)).collect(Collectors.toList());
|
||||
List<S> mainStmts = ctx.programBody.stream().map(stmt -> statementVisitor.visit(stmt))
|
||||
.collect(Collectors.toList());
|
||||
if (mainStmts.size() == 1) {
|
||||
main = mainStmts.get(0);
|
||||
} else {
|
||||
main = factory.createSequenceStatement(mainStmts, toSourceLocation(ctx));
|
||||
}
|
||||
assert main != null;
|
||||
return null;
|
||||
}
|
||||
|
||||
private class ProcedureDefinitionVisitor extends WormsProgramBaseVisitor<P> {
|
||||
|
||||
@Override
|
||||
public P visitProceduredef(ProceduredefContext ctx) {
|
||||
return getFactory().createProcedureDefinition(ctx.procname.getText(), statementVisitor.visit(ctx.body),
|
||||
toSourceLocation(ctx));
|
||||
}
|
||||
}
|
||||
|
||||
private class StatementVisitor extends WormsProgramBaseVisitor<S> {
|
||||
|
||||
@Override
|
||||
public S visitAssignmentStatement(AssignmentStatementContext ctx) {
|
||||
return getFactory().createAssignmentStatement(ctx.variableName.getText(),
|
||||
expressionVisitor.visit(ctx.value), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public S visitWhileStatement(WhileStatementContext ctx) {
|
||||
return getFactory().createWhileStatement(expressionVisitor.visit(ctx.condition),
|
||||
statementVisitor.visit(ctx.body), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public S visitIfStatement(IfStatementContext ctx) {
|
||||
S ifBody = statementVisitor.visit(ctx.ifbody);
|
||||
S elseBody = null;
|
||||
if (ctx.elsebody != null)
|
||||
elseBody = statementVisitor.visit(ctx.elsebody);
|
||||
return getFactory().createIfStatement(expressionVisitor.visit(ctx.condition), ifBody, elseBody,
|
||||
toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public S visitPrintStatement(PrintStatementContext ctx) {
|
||||
return getFactory().createPrintStatement(expressionVisitor.visit(ctx.value), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public S visitSequenceStatement(SequenceStatementContext ctx) {
|
||||
if (ctx.stmts.size() != 1) {
|
||||
return getFactory().createSequenceStatement(
|
||||
ctx.stmts.stream().map(this::visit).collect(Collectors.toList()), toSourceLocation(ctx));
|
||||
} else {
|
||||
return visit(ctx.stmts.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public S visitInvokeStatement(InvokeStatementContext ctx) {
|
||||
return getFactory().createInvokeStatement(ctx.procName.getText(), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public S visitBreakStatement(BreakStatementContext ctx) {
|
||||
return getFactory().createBreakStatement(toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public S visitTurnAction(TurnActionContext ctx) {
|
||||
return getFactory().createTurnStatement(expressionVisitor.visit(ctx.angle), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public S visitMoveAction(MoveActionContext ctx) {
|
||||
return getFactory().createMoveStatement(toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public S visitJumpAction(JumpActionContext ctx) {
|
||||
return getFactory().createJumpStatement(toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public S visitEatAction(EatActionContext ctx) {
|
||||
return getFactory().createEatStatement(toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public S visitFireAction(FireActionContext ctx) {
|
||||
return getFactory().createFireStatement(toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class ExpressionVisitor extends WormsProgramBaseVisitor<E> {
|
||||
|
||||
@Override
|
||||
public E visitReadVariableExpression(ReadVariableExpressionContext ctx) {
|
||||
return getFactory().createReadVariableExpression(ctx.variable.getText(), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitConstantExpression(ConstantExpressionContext ctx) {
|
||||
return getFactory().createDoubleLiteralExpression(Double.parseDouble(ctx.value.getText()),
|
||||
toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitTrueLiteralExpression(TrueLiteralExpressionContext ctx) {
|
||||
return getFactory().createBooleanLiteralExpression(true, toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitFalseLiteralExpression(FalseLiteralExpressionContext ctx) {
|
||||
return getFactory().createBooleanLiteralExpression(false, toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitNullExpression(NullExpressionContext ctx) {
|
||||
return getFactory().createNullExpression(toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitSelfExpression(SelfExpressionContext ctx) {
|
||||
return getFactory().createSelfExpression(toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitParenExpression(ParenExpressionContext ctx) {
|
||||
return expressionVisitor.visit(ctx.subExpr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitAddSubExpression(AddSubExpressionContext ctx) {
|
||||
switch (ctx.op.getType()) {
|
||||
case WormsProgramLexer.ADD:
|
||||
return getFactory().createAdditionExpression(expressionVisitor.visit(ctx.left),
|
||||
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
|
||||
case WormsProgramLexer.SUB:
|
||||
return getFactory().createSubtractionExpression(expressionVisitor.visit(ctx.left),
|
||||
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown operator: " + ctx.op);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitMulDivExpression(MulDivExpressionContext ctx) {
|
||||
switch (ctx.op.getType()) {
|
||||
case WormsProgramLexer.MUL:
|
||||
return getFactory().createMultiplicationExpression(expressionVisitor.visit(ctx.left),
|
||||
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
|
||||
case WormsProgramLexer.DIV:
|
||||
return getFactory().createDivisionExpression(expressionVisitor.visit(ctx.left),
|
||||
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown operator: " + ctx.op);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitSqrtExpression(SqrtExpressionContext ctx) {
|
||||
return getFactory().createSqrtExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitSinExpression(SinExpressionContext ctx) {
|
||||
return getFactory().createSinExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitCosExpression(CosExpressionContext ctx) {
|
||||
return getFactory().createCosExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitAndOrExpression(AndOrExpressionContext ctx) {
|
||||
switch (ctx.op.getType()) {
|
||||
case WormsProgramLexer.AND:
|
||||
return getFactory().createAndExpression(expressionVisitor.visit(ctx.left),
|
||||
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
|
||||
case WormsProgramLexer.OR:
|
||||
return getFactory().createOrExpression(expressionVisitor.visit(ctx.left),
|
||||
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown operator: " + ctx.op);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitNotExpression(NotExpressionContext ctx) {
|
||||
return getFactory().createNotExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitComparisonExpression(ComparisonExpressionContext ctx) {
|
||||
switch (ctx.op.getType()) {
|
||||
case WormsProgramLexer.LT:
|
||||
return getFactory().createLessThanExpression(expressionVisitor.visit(ctx.left),
|
||||
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
|
||||
case WormsProgramLexer.LTE:
|
||||
return getFactory().createLessThanOrEqualExpression(expressionVisitor.visit(ctx.left),
|
||||
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
|
||||
case WormsProgramLexer.GT:
|
||||
return getFactory().createGreaterThanExpression(expressionVisitor.visit(ctx.left),
|
||||
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
|
||||
case WormsProgramLexer.GTE:
|
||||
return getFactory().createGreaterThanOrEqualExpression(expressionVisitor.visit(ctx.left),
|
||||
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
|
||||
case WormsProgramLexer.EQ:
|
||||
return getFactory().createEqualityExpression(expressionVisitor.visit(ctx.left),
|
||||
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
|
||||
case WormsProgramLexer.NEQ:
|
||||
return getFactory().createInequalityExpression(expressionVisitor.visit(ctx.left),
|
||||
expressionVisitor.visit(ctx.right), toSourceLocation(ctx));
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown operand: " + ctx.op);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitGetXExpression(GetXExpressionContext ctx) {
|
||||
return getFactory().createGetXExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitGetYExpression(GetYExpressionContext ctx) {
|
||||
return getFactory().createGetYExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitGetRadiusExpression(GetRadiusExpressionContext ctx) {
|
||||
return getFactory().createGetRadiusExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitGetDirectionExpression(GetDirectionExpressionContext ctx) {
|
||||
return getFactory().createGetDirectionExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitGetAPExpression(GetAPExpressionContext ctx) {
|
||||
return getFactory().createGetActionPointsExpression(expressionVisitor.visit(ctx.expr),
|
||||
toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitGetMaxAPExpression(GetMaxAPExpressionContext ctx) {
|
||||
return getFactory().createGetMaxActionPointsExpression(expressionVisitor.visit(ctx.expr),
|
||||
toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitGetHPExpression(GetHPExpressionContext ctx) {
|
||||
return getFactory().createHitPointsExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitSameTeamExpression(SameTeamExpressionContext ctx) {
|
||||
return getFactory().createSameTeamExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitSearchObjExpression(SearchObjExpressionContext ctx) {
|
||||
return getFactory().createSearchObjectExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitDistanceExpression(DistanceExpressionContext ctx) {
|
||||
return getFactory().createDistanceExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitIsWormExpression(IsWormExpressionContext ctx) {
|
||||
return getFactory().createIsWormExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitIsFoodExpression(IsFoodExpressionContext ctx) {
|
||||
return getFactory().createIsFoodExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E visitIsProjectileExpression(IsProjectileExpressionContext ctx) {
|
||||
return getFactory().createIsProjectileExpression(expressionVisitor.visit(ctx.expr), toSourceLocation(ctx));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final IProgramFactory<E, S, P, Prg> factory;
|
||||
|
||||
private final ProcedureDefinitionVisitor procDefVisitor = new ProcedureDefinitionVisitor();
|
||||
private final StatementVisitor statementVisitor = new StatementVisitor();
|
||||
private final ExpressionVisitor expressionVisitor = new ExpressionVisitor();
|
||||
|
||||
private S main;
|
||||
private List<P> procedures;
|
||||
|
||||
public ParserVisitor(IProgramFactory<E, S, P, Prg> factory) {
|
||||
if (factory == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
private SourceLocation toSourceLocation(ParserRuleContext ctx) {
|
||||
int line = ctx.getStart().getLine();
|
||||
int column = ctx.getStart().getCharPositionInLine();
|
||||
return new SourceLocation(line, column);
|
||||
}
|
||||
|
||||
public IProgramFactory<E, S, P, Prg> getFactory() {
|
||||
return factory;
|
||||
}
|
||||
|
||||
public int toInt(Token z) {
|
||||
return Integer.parseInt(z.getText());
|
||||
}
|
||||
|
||||
public S getMain() {
|
||||
return main;
|
||||
}
|
||||
|
||||
public List<P> getProcedures() {
|
||||
return Collections.unmodifiableList(procedures);
|
||||
}
|
||||
|
||||
}
|
200
OGP1718-Worms/src-provided/worms/programs/internal/parser/WormsProgram.g4
Executable file
200
OGP1718-Worms/src-provided/worms/programs/internal/parser/WormsProgram.g4
Executable file
@@ -0,0 +1,200 @@
|
||||
// ANTLR v4 Grammar for controling Worms.
|
||||
// Check the tutorial at http://jnb.ociweb.com/jnb/jnbJun2008.html
|
||||
// or http://www.antlr.org/ for details.
|
||||
|
||||
|
||||
grammar WormsProgram;
|
||||
|
||||
@header {
|
||||
package worms.programs.internal.parser.generated;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// --- Eval and Related Definitions ---------------------------------------
|
||||
// ------------------------------------------------------------------------
|
||||
program: (procdef+=proceduredef)*
|
||||
(programBody+=statement)*
|
||||
;
|
||||
|
||||
proceduredef: DEF procname=IDENTIFIER COLON?
|
||||
body=statement
|
||||
;
|
||||
|
||||
statement: assignmentStatement
|
||||
| whileStatement
|
||||
| ifStatement
|
||||
| printStatement
|
||||
| sequenceStatement
|
||||
| invokeStatement
|
||||
| breakStatement
|
||||
| actionStatement
|
||||
;
|
||||
|
||||
assignmentStatement: variableName=IDENTIFIER ASSIGN value=expression ';'
|
||||
;
|
||||
|
||||
whileStatement: WHILE condition=expression COLON?
|
||||
body=statement
|
||||
;
|
||||
|
||||
ifStatement: IF condition=expression COLON?
|
||||
ifbody=statement
|
||||
(ELSE COLON?
|
||||
elsebody=statement)?
|
||||
;
|
||||
|
||||
printStatement: PRINT value=expression ';'
|
||||
;
|
||||
|
||||
sequenceStatement: LEFT_BRACE (stmts+=statement)* RIGHT_BRACE
|
||||
;
|
||||
|
||||
invokeStatement: INVOKE procName=IDENTIFIER ';'
|
||||
;
|
||||
|
||||
|
||||
breakStatement: BREAK ';'
|
||||
;
|
||||
|
||||
|
||||
actionStatement: TURN angle=expression ';' #turnAction
|
||||
| MOVE ';' #moveAction
|
||||
| JUMP ';' #jumpAction
|
||||
| EAT ';' #eatAction
|
||||
| FIRE ';' #fireAction
|
||||
;
|
||||
|
||||
// order here sets order of operations (important for left-recursive expressions!)
|
||||
expression: variable=IDENTIFIER #readVariableExpression
|
||||
| value=NUMBER #constantExpression
|
||||
| TRUE #trueLiteralExpression
|
||||
| FALSE #falseLiteralExpression
|
||||
| NULL #nullExpression
|
||||
| SELF #selfExpression
|
||||
| LEFT_PAREN subExpr=expression RIGHT_PAREN #parenExpression
|
||||
| left=expression op=(MUL | DIV) right=expression #mulDivExpression
|
||||
| left=expression op=(ADD | SUB) right=expression #addSubExpression
|
||||
| left=expression op=(LT | LTE | GT | GTE | EQ | NEQ) right=expression #comparisonExpression
|
||||
| left=expression op=(AND | OR) right=expression #andOrExpression
|
||||
| SQRT LEFT_PAREN expr=expression RIGHT_PAREN #sqrtExpression
|
||||
| SIN LEFT_PAREN expr=expression RIGHT_PAREN #sinExpression
|
||||
| COS LEFT_PAREN expr=expression RIGHT_PAREN #cosExpression
|
||||
| NOT expr=expression #notExpression
|
||||
| GETX expr=expression #getXExpression
|
||||
| GETY expr=expression #getYExpression
|
||||
| GETRADIUS expr=expression #getRadiusExpression
|
||||
| GETDIR expr=expression #getDirectionExpression
|
||||
| GETAP expr=expression #getAPExpression
|
||||
| GETMAXAP expr=expression #getMaxAPExpression
|
||||
| GETHP expr=expression #getHPExpression
|
||||
| SAMETEAM expr=expression #sameTeamExpression
|
||||
| SEARCHOBJ expr=expression #searchObjExpression
|
||||
| DISTANCE expr=expression #distanceExpression
|
||||
| ISWORM expr=expression #isWormExpression
|
||||
| ISFOOD expr=expression #isFoodExpression
|
||||
| ISPROJECTILE expr=expression #isProjectileExpression
|
||||
;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// --- Specifiers -----------------------------------------------
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
NULL: 'null';
|
||||
SELF: 'self';
|
||||
TRUE: 'true';
|
||||
FALSE: 'false';
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// --- Unary Operations ---------------------------------------------------
|
||||
// ------------------------------------------------------------------------
|
||||
SQRT: 'sqrt';
|
||||
SIN: 'sin';
|
||||
COS: 'cos';
|
||||
NOT: '!';
|
||||
GETX: 'getx';
|
||||
GETY: 'gety';
|
||||
GETRADIUS: 'getradius';
|
||||
GETDIR: 'getdir';
|
||||
GETAP: 'getap';
|
||||
GETMAXAP: 'getmaxap';
|
||||
GETHP: 'gethp';
|
||||
SAMETEAM: 'sameteam';
|
||||
SEARCHOBJ: 'searchobj';
|
||||
DISTANCE: 'distance';
|
||||
ISWORM: 'isworm';
|
||||
ISFOOD: 'isfood';
|
||||
ISPROJECTILE: 'isprojectile';
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// --- Actions -----------------------------------------------
|
||||
// ------------------------------------------------------------------------
|
||||
TURN: 'turn';
|
||||
MOVE: 'move';
|
||||
JUMP: 'jump';
|
||||
EAT: 'eat';
|
||||
FIRE: 'fire';
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// --- Control Flow -------------------------------------------------------
|
||||
// ------------------------------------------------------------------------
|
||||
DEF: 'def';
|
||||
IF: 'if';
|
||||
INVOKE: 'invoke';
|
||||
THEN: 'then';
|
||||
ELSE: 'else';
|
||||
WHILE: 'while';
|
||||
BREAK: 'break';
|
||||
PRINT: 'print';
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// --- Assignment and Arithmetics -----------------------------------------
|
||||
// ------------------------------------------------------------------------
|
||||
ASSIGN: ':=';
|
||||
ADD: '+';
|
||||
SUB: '-';
|
||||
MUL: '*';
|
||||
DIV: '/';
|
||||
AND: '&&';
|
||||
OR: '||';
|
||||
LT: '<';
|
||||
LTE: '<=';
|
||||
GT: '>';
|
||||
GTE: '>=';
|
||||
EQ: '==';
|
||||
NEQ: '!=';
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// --- Literals and Variables ---------------------------------------------
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
NUMBER: INTEGER | FLOAT;
|
||||
FLOAT: INTEGER '.' ('0'..'9')+;
|
||||
INTEGER: ('-'|'+')? ('0'..'9')+;
|
||||
|
||||
IDENTIFIER: LETTER (LETTER | DIGIT | '_')*;
|
||||
fragment LETTER: LOWER | UPPER;
|
||||
fragment LOWER: 'a'..'z';
|
||||
fragment UPPER: 'A'..'Z';
|
||||
fragment DIGIT: '0'..'9';
|
||||
|
||||
LEFT_PAREN: '(';
|
||||
RIGHT_PAREN: ')';
|
||||
LEFT_BRACE: '{';
|
||||
RIGHT_BRACE: '}';
|
||||
COLON: ':';
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// --- Syntactical Ballast ------------------------------------------------
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// Skip runs of newline, space and tab characters.
|
||||
WHITESPACE: [ \t\r\n]+ -> skip;
|
||||
|
||||
// Single-line comments begin with //, are followed by any characters
|
||||
// other than those in a newline, and are terminated by newline characters.
|
||||
SINGLE_COMMENT: '//' ~('\r' | '\n')* NEWLINE -> skip;
|
||||
fragment NEWLINE: ('\r'? '\n')+;
|
||||
|
@@ -0,0 +1,42 @@
|
||||
package worms.programs.internal.parser.example;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import worms.programs.IProgramFactory;
|
||||
import worms.programs.ParseOutcome;
|
||||
import worms.programs.ProgramParser;
|
||||
|
||||
public class ExamplePrinter {
|
||||
public static void main(String[] args) throws IOException {
|
||||
IProgramFactory<PrintingObject, PrintingObject, PrintingObject, PrintingProgram> factory = PrintingObjectFactory.create();
|
||||
ProgramParser<?, ?, ?, PrintingProgram> parser = ProgramParser.create(factory);
|
||||
|
||||
/*
|
||||
ParseOutcome<PrintingProgram> outcome = parser.parseString(
|
||||
"def controlled_move:"
|
||||
+ " if getap self > 100.0:"
|
||||
+ " { jump; print getx self; print gety self; }"
|
||||
+ " else move;"
|
||||
+ ""
|
||||
+ "max_distance := 10.0;"
|
||||
+ "while true: {"
|
||||
+ " w := searchobj 0.0;"
|
||||
+ " if isworm w: {"
|
||||
+ " if sameteam w:"
|
||||
+ " invoke controlled_move;"
|
||||
+ " else if distance w < max_distance:"
|
||||
+ " fire;"
|
||||
+ " else"
|
||||
+ " { turn d; max_distance := max_distance + 0.1; }"
|
||||
+ " }"
|
||||
+ "}");
|
||||
*/
|
||||
//ParseOutcome<PrintingProgram> outcome = parser.parseFile("programs/program_example.txt");
|
||||
//ParseOutcome<PrintingProgram> outcome = parser.parseFile("programs/syntax_test.txt");
|
||||
ParseOutcome<PrintingProgram> outcome = parser.parseFile("programs/program.txt");
|
||||
|
||||
System.out.println(outcome);
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,80 @@
|
||||
package worms.programs.internal.parser.example;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import worms.programs.SourceLocation;
|
||||
|
||||
public class PrintingObject {
|
||||
|
||||
private boolean indented = false;
|
||||
|
||||
private final StringBuilder repr = new StringBuilder();
|
||||
|
||||
public PrintingObject(SourceLocation loc, String method, Object... args) {
|
||||
if (loc != null) {
|
||||
method = loc + " " + method;
|
||||
}
|
||||
if (args.length > 1) {
|
||||
indented(method + "(");
|
||||
indented = true;
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
indented(repr(args[i]), args.length > 1 && i < args.length - 1);
|
||||
}
|
||||
indented = false;
|
||||
indented(")");
|
||||
} else {
|
||||
String msg = method + "( ";
|
||||
if (args.length > 0) {
|
||||
msg += repr(args[0]).toString().trim();
|
||||
}
|
||||
msg += " )";
|
||||
indented(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private String repr(Object object) {
|
||||
if (object instanceof String) {
|
||||
object = "\"" + object + "\"";
|
||||
} else if (object instanceof List<?>) {
|
||||
object = String.format("Arrays.toList(%s)", ((List<?>) object)
|
||||
.stream().map(this::repr)
|
||||
.collect(Collectors.joining(", ### Arrays.toList\n")));
|
||||
}
|
||||
if (object != null) {
|
||||
return object.toString();
|
||||
} else {
|
||||
return "null";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return repr.toString();
|
||||
}
|
||||
|
||||
private void indented(Object object) {
|
||||
indented(object, false);
|
||||
}
|
||||
|
||||
private void indented(Object object, boolean appendComma) {
|
||||
if (object != null) {
|
||||
String str = object.toString();
|
||||
StringTokenizer tok = new StringTokenizer(str, "\n");
|
||||
while (tok.hasMoreTokens()) {
|
||||
if (indented)
|
||||
repr.append("| ");
|
||||
repr.append(tok.nextToken());
|
||||
if (!tok.hasMoreTokens() && appendComma) {
|
||||
repr.append(",");
|
||||
}
|
||||
repr.append("\n");
|
||||
}
|
||||
} else {
|
||||
if (indented)
|
||||
repr.append(" null");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
package worms.programs.internal.parser.example;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import worms.programs.IProgramFactory;
|
||||
import worms.programs.SourceLocation;
|
||||
|
||||
|
||||
public class PrintingObjectFactory {
|
||||
|
||||
/**
|
||||
* Creates an implementation of IProgramFactory where the implementation of
|
||||
* each interface method (except createProgram) just creates a
|
||||
* PrintingObject with all arguments.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static IProgramFactory<PrintingObject, PrintingObject, PrintingObject, PrintingProgram> create() {
|
||||
|
||||
InvocationHandler handler = new InvocationHandler() {
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
if (method.getName().equals("createProgram")) {
|
||||
List<PrintingObject> functions = (List<PrintingObject>)args[0];
|
||||
PrintingObject main = (PrintingObject) args[1];
|
||||
return new PrintingProgram(functions, main);
|
||||
}
|
||||
if (args != null) {
|
||||
SourceLocation sourceLocation = (SourceLocation) args[args.length - 1];
|
||||
if (args.length >= 1) {
|
||||
return new PrintingObject(sourceLocation, method.getName(),
|
||||
Arrays.copyOfRange(args, 0, args.length - 1));
|
||||
} else {
|
||||
return new PrintingObject(sourceLocation, method.getName());
|
||||
}
|
||||
} else {
|
||||
return new PrintingObject(null, method.getName());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (IProgramFactory<PrintingObject, PrintingObject, PrintingObject, PrintingProgram>) Proxy.newProxyInstance(
|
||||
IProgramFactory.class.getClassLoader(), new Class[] { IProgramFactory.class }, handler);
|
||||
}
|
||||
}
|
@@ -0,0 +1,22 @@
|
||||
package worms.programs.internal.parser.example;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PrintingProgram {
|
||||
|
||||
private List<PrintingObject> procedures;
|
||||
private PrintingObject main;
|
||||
|
||||
public PrintingProgram(List<PrintingObject> procedures, PrintingObject main) {
|
||||
if (main == null) {
|
||||
throw new NullPointerException("main null");
|
||||
}
|
||||
this.main = main;
|
||||
this.procedures = procedures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Procedures: " + procedures.toString() + "\nMain:" + main.toString();
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
@@ -0,0 +1,112 @@
|
||||
T__0=1
|
||||
NULL=2
|
||||
SELF=3
|
||||
TRUE=4
|
||||
FALSE=5
|
||||
SQRT=6
|
||||
SIN=7
|
||||
COS=8
|
||||
NOT=9
|
||||
GETX=10
|
||||
GETY=11
|
||||
GETRADIUS=12
|
||||
GETDIR=13
|
||||
GETAP=14
|
||||
GETMAXAP=15
|
||||
GETHP=16
|
||||
SAMETEAM=17
|
||||
SEARCHOBJ=18
|
||||
DISTANCE=19
|
||||
ISWORM=20
|
||||
ISFOOD=21
|
||||
ISPROJECTILE=22
|
||||
TURN=23
|
||||
MOVE=24
|
||||
JUMP=25
|
||||
EAT=26
|
||||
FIRE=27
|
||||
DEF=28
|
||||
IF=29
|
||||
INVOKE=30
|
||||
THEN=31
|
||||
ELSE=32
|
||||
WHILE=33
|
||||
BREAK=34
|
||||
PRINT=35
|
||||
ASSIGN=36
|
||||
ADD=37
|
||||
SUB=38
|
||||
MUL=39
|
||||
DIV=40
|
||||
AND=41
|
||||
OR=42
|
||||
LT=43
|
||||
LTE=44
|
||||
GT=45
|
||||
GTE=46
|
||||
EQ=47
|
||||
NEQ=48
|
||||
NUMBER=49
|
||||
FLOAT=50
|
||||
INTEGER=51
|
||||
IDENTIFIER=52
|
||||
LEFT_PAREN=53
|
||||
RIGHT_PAREN=54
|
||||
LEFT_BRACE=55
|
||||
RIGHT_BRACE=56
|
||||
COLON=57
|
||||
WHITESPACE=58
|
||||
SINGLE_COMMENT=59
|
||||
';'=1
|
||||
'null'=2
|
||||
'self'=3
|
||||
'true'=4
|
||||
'false'=5
|
||||
'sqrt'=6
|
||||
'sin'=7
|
||||
'cos'=8
|
||||
'!'=9
|
||||
'getx'=10
|
||||
'gety'=11
|
||||
'getradius'=12
|
||||
'getdir'=13
|
||||
'getap'=14
|
||||
'getmaxap'=15
|
||||
'gethp'=16
|
||||
'sameteam'=17
|
||||
'searchobj'=18
|
||||
'distance'=19
|
||||
'isworm'=20
|
||||
'isfood'=21
|
||||
'isprojectile'=22
|
||||
'turn'=23
|
||||
'move'=24
|
||||
'jump'=25
|
||||
'eat'=26
|
||||
'fire'=27
|
||||
'def'=28
|
||||
'if'=29
|
||||
'invoke'=30
|
||||
'then'=31
|
||||
'else'=32
|
||||
'while'=33
|
||||
'break'=34
|
||||
'print'=35
|
||||
':='=36
|
||||
'+'=37
|
||||
'-'=38
|
||||
'*'=39
|
||||
'/'=40
|
||||
'&&'=41
|
||||
'||'=42
|
||||
'<'=43
|
||||
'<='=44
|
||||
'>'=45
|
||||
'>='=46
|
||||
'=='=47
|
||||
'!='=48
|
||||
'('=53
|
||||
')'=54
|
||||
'{'=55
|
||||
'}'=56
|
||||
':'=57
|
@@ -0,0 +1,317 @@
|
||||
// Generated from WormsProgram.g4 by ANTLR 4.7.1
|
||||
|
||||
package worms.programs.internal.parser.generated;
|
||||
|
||||
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
|
||||
|
||||
/**
|
||||
* This class provides an empty implementation of {@link WormsProgramVisitor},
|
||||
* which can be extended to create a visitor which only needs to handle a subset
|
||||
* of the available methods.
|
||||
*
|
||||
* @param <T> The return type of the visit operation. Use {@link Void} for
|
||||
* operations with no return type.
|
||||
*/
|
||||
public class WormsProgramBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements WormsProgramVisitor<T> {
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitProgram(WormsProgramParser.ProgramContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitProceduredef(WormsProgramParser.ProceduredefContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitStatement(WormsProgramParser.StatementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitAssignmentStatement(WormsProgramParser.AssignmentStatementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitWhileStatement(WormsProgramParser.WhileStatementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitIfStatement(WormsProgramParser.IfStatementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitPrintStatement(WormsProgramParser.PrintStatementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitSequenceStatement(WormsProgramParser.SequenceStatementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitInvokeStatement(WormsProgramParser.InvokeStatementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitBreakStatement(WormsProgramParser.BreakStatementContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitTurnAction(WormsProgramParser.TurnActionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitMoveAction(WormsProgramParser.MoveActionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitJumpAction(WormsProgramParser.JumpActionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitEatAction(WormsProgramParser.EatActionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitFireAction(WormsProgramParser.FireActionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitDistanceExpression(WormsProgramParser.DistanceExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitCosExpression(WormsProgramParser.CosExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGetYExpression(WormsProgramParser.GetYExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitAndOrExpression(WormsProgramParser.AndOrExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitIsWormExpression(WormsProgramParser.IsWormExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitNotExpression(WormsProgramParser.NotExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitComparisonExpression(WormsProgramParser.ComparisonExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitParenExpression(WormsProgramParser.ParenExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGetRadiusExpression(WormsProgramParser.GetRadiusExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitTrueLiteralExpression(WormsProgramParser.TrueLiteralExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitNullExpression(WormsProgramParser.NullExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitSqrtExpression(WormsProgramParser.SqrtExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitSinExpression(WormsProgramParser.SinExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitSameTeamExpression(WormsProgramParser.SameTeamExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitIsProjectileExpression(WormsProgramParser.IsProjectileExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitIsFoodExpression(WormsProgramParser.IsFoodExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitConstantExpression(WormsProgramParser.ConstantExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitSearchObjExpression(WormsProgramParser.SearchObjExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGetXExpression(WormsProgramParser.GetXExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitReadVariableExpression(WormsProgramParser.ReadVariableExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitMulDivExpression(WormsProgramParser.MulDivExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGetDirectionExpression(WormsProgramParser.GetDirectionExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitSelfExpression(WormsProgramParser.SelfExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGetHPExpression(WormsProgramParser.GetHPExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitAddSubExpression(WormsProgramParser.AddSubExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGetMaxAPExpression(WormsProgramParser.GetMaxAPExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitGetAPExpression(WormsProgramParser.GetAPExpressionContext ctx) { return visitChildren(ctx); }
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* <p>The default implementation returns the result of calling
|
||||
* {@link #visitChildren} on {@code ctx}.</p>
|
||||
*/
|
||||
@Override public T visitFalseLiteralExpression(WormsProgramParser.FalseLiteralExpressionContext ctx) { return visitChildren(ctx); }
|
||||
}
|
File diff suppressed because one or more lines are too long
@@ -0,0 +1,280 @@
|
||||
// Generated from WormsProgram.g4 by ANTLR 4.7.1
|
||||
|
||||
package worms.programs.internal.parser.generated;
|
||||
|
||||
import org.antlr.v4.runtime.Lexer;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.TokenStream;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.misc.*;
|
||||
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||
public class WormsProgramLexer extends Lexer {
|
||||
static { RuntimeMetaData.checkVersion("4.7.1", RuntimeMetaData.VERSION); }
|
||||
|
||||
protected static final DFA[] _decisionToDFA;
|
||||
protected static final PredictionContextCache _sharedContextCache =
|
||||
new PredictionContextCache();
|
||||
public static final int
|
||||
T__0=1, NULL=2, SELF=3, TRUE=4, FALSE=5, SQRT=6, SIN=7, COS=8, NOT=9,
|
||||
GETX=10, GETY=11, GETRADIUS=12, GETDIR=13, GETAP=14, GETMAXAP=15, GETHP=16,
|
||||
SAMETEAM=17, SEARCHOBJ=18, DISTANCE=19, ISWORM=20, ISFOOD=21, ISPROJECTILE=22,
|
||||
TURN=23, MOVE=24, JUMP=25, EAT=26, FIRE=27, DEF=28, IF=29, INVOKE=30,
|
||||
THEN=31, ELSE=32, WHILE=33, BREAK=34, PRINT=35, ASSIGN=36, ADD=37, SUB=38,
|
||||
MUL=39, DIV=40, AND=41, OR=42, LT=43, LTE=44, GT=45, GTE=46, EQ=47, NEQ=48,
|
||||
NUMBER=49, FLOAT=50, INTEGER=51, IDENTIFIER=52, LEFT_PAREN=53, RIGHT_PAREN=54,
|
||||
LEFT_BRACE=55, RIGHT_BRACE=56, COLON=57, WHITESPACE=58, SINGLE_COMMENT=59;
|
||||
public static String[] channelNames = {
|
||||
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
|
||||
};
|
||||
|
||||
public static String[] modeNames = {
|
||||
"DEFAULT_MODE"
|
||||
};
|
||||
|
||||
public static final String[] ruleNames = {
|
||||
"T__0", "NULL", "SELF", "TRUE", "FALSE", "SQRT", "SIN", "COS", "NOT",
|
||||
"GETX", "GETY", "GETRADIUS", "GETDIR", "GETAP", "GETMAXAP", "GETHP", "SAMETEAM",
|
||||
"SEARCHOBJ", "DISTANCE", "ISWORM", "ISFOOD", "ISPROJECTILE", "TURN", "MOVE",
|
||||
"JUMP", "EAT", "FIRE", "DEF", "IF", "INVOKE", "THEN", "ELSE", "WHILE",
|
||||
"BREAK", "PRINT", "ASSIGN", "ADD", "SUB", "MUL", "DIV", "AND", "OR", "LT",
|
||||
"LTE", "GT", "GTE", "EQ", "NEQ", "NUMBER", "FLOAT", "INTEGER", "IDENTIFIER",
|
||||
"LETTER", "LOWER", "UPPER", "DIGIT", "LEFT_PAREN", "RIGHT_PAREN", "LEFT_BRACE",
|
||||
"RIGHT_BRACE", "COLON", "WHITESPACE", "SINGLE_COMMENT", "NEWLINE"
|
||||
};
|
||||
|
||||
private static final String[] _LITERAL_NAMES = {
|
||||
null, "';'", "'null'", "'self'", "'true'", "'false'", "'sqrt'", "'sin'",
|
||||
"'cos'", "'!'", "'getx'", "'gety'", "'getradius'", "'getdir'", "'getap'",
|
||||
"'getmaxap'", "'gethp'", "'sameteam'", "'searchobj'", "'distance'", "'isworm'",
|
||||
"'isfood'", "'isprojectile'", "'turn'", "'move'", "'jump'", "'eat'", "'fire'",
|
||||
"'def'", "'if'", "'invoke'", "'then'", "'else'", "'while'", "'break'",
|
||||
"'print'", "':='", "'+'", "'-'", "'*'", "'/'", "'&&'", "'||'", "'<'",
|
||||
"'<='", "'>'", "'>='", "'=='", "'!='", null, null, null, null, "'('",
|
||||
"')'", "'{'", "'}'", "':'"
|
||||
};
|
||||
private static final String[] _SYMBOLIC_NAMES = {
|
||||
null, null, "NULL", "SELF", "TRUE", "FALSE", "SQRT", "SIN", "COS", "NOT",
|
||||
"GETX", "GETY", "GETRADIUS", "GETDIR", "GETAP", "GETMAXAP", "GETHP", "SAMETEAM",
|
||||
"SEARCHOBJ", "DISTANCE", "ISWORM", "ISFOOD", "ISPROJECTILE", "TURN", "MOVE",
|
||||
"JUMP", "EAT", "FIRE", "DEF", "IF", "INVOKE", "THEN", "ELSE", "WHILE",
|
||||
"BREAK", "PRINT", "ASSIGN", "ADD", "SUB", "MUL", "DIV", "AND", "OR", "LT",
|
||||
"LTE", "GT", "GTE", "EQ", "NEQ", "NUMBER", "FLOAT", "INTEGER", "IDENTIFIER",
|
||||
"LEFT_PAREN", "RIGHT_PAREN", "LEFT_BRACE", "RIGHT_BRACE", "COLON", "WHITESPACE",
|
||||
"SINGLE_COMMENT"
|
||||
};
|
||||
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #VOCABULARY} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String[] tokenNames;
|
||||
static {
|
||||
tokenNames = new String[_SYMBOLIC_NAMES.length];
|
||||
for (int i = 0; i < tokenNames.length; i++) {
|
||||
tokenNames[i] = VOCABULARY.getLiteralName(i);
|
||||
if (tokenNames[i] == null) {
|
||||
tokenNames[i] = VOCABULARY.getSymbolicName(i);
|
||||
}
|
||||
|
||||
if (tokenNames[i] == null) {
|
||||
tokenNames[i] = "<INVALID>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String[] getTokenNames() {
|
||||
return tokenNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public Vocabulary getVocabulary() {
|
||||
return VOCABULARY;
|
||||
}
|
||||
|
||||
|
||||
public WormsProgramLexer(CharStream input) {
|
||||
super(input);
|
||||
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGrammarFileName() { return "WormsProgram.g4"; }
|
||||
|
||||
@Override
|
||||
public String[] getRuleNames() { return ruleNames; }
|
||||
|
||||
@Override
|
||||
public String getSerializedATN() { return _serializedATN; }
|
||||
|
||||
@Override
|
||||
public String[] getChannelNames() { return channelNames; }
|
||||
|
||||
@Override
|
||||
public String[] getModeNames() { return modeNames; }
|
||||
|
||||
@Override
|
||||
public ATN getATN() { return _ATN; }
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2=\u01bf\b\1\4\2\t"+
|
||||
"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
|
||||
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
|
||||
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
|
||||
"\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+
|
||||
"\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+
|
||||
",\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64\t"+
|
||||
"\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t="+
|
||||
"\4>\t>\4?\t?\4@\t@\4A\tA\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3"+
|
||||
"\4\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\b"+
|
||||
"\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\f\3\f"+
|
||||
"\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16\3\16\3\16\3"+
|
||||
"\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3"+
|
||||
"\20\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3"+
|
||||
"\22\3\22\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3"+
|
||||
"\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3"+
|
||||
"\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3\26\3\26\3\27\3\27\3\27\3"+
|
||||
"\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3"+
|
||||
"\30\3\31\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3"+
|
||||
"\33\3\34\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\37\3"+
|
||||
"\37\3\37\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3 \3!\3!\3!\3!\3!\3\"\3\"\3\""+
|
||||
"\3\"\3\"\3\"\3#\3#\3#\3#\3#\3#\3$\3$\3$\3$\3$\3$\3%\3%\3%\3&\3&\3\'\3"+
|
||||
"\'\3(\3(\3)\3)\3*\3*\3*\3+\3+\3+\3,\3,\3-\3-\3-\3.\3.\3/\3/\3/\3\60\3"+
|
||||
"\60\3\60\3\61\3\61\3\61\3\62\3\62\5\62\u0176\n\62\3\63\3\63\3\63\6\63"+
|
||||
"\u017b\n\63\r\63\16\63\u017c\3\64\5\64\u0180\n\64\3\64\6\64\u0183\n\64"+
|
||||
"\r\64\16\64\u0184\3\65\3\65\3\65\3\65\7\65\u018b\n\65\f\65\16\65\u018e"+
|
||||
"\13\65\3\66\3\66\5\66\u0192\n\66\3\67\3\67\38\38\39\39\3:\3:\3;\3;\3<"+
|
||||
"\3<\3=\3=\3>\3>\3?\6?\u01a5\n?\r?\16?\u01a6\3?\3?\3@\3@\3@\3@\7@\u01af"+
|
||||
"\n@\f@\16@\u01b2\13@\3@\3@\3@\3@\3A\5A\u01b9\nA\3A\6A\u01bc\nA\rA\16A"+
|
||||
"\u01bd\2\2B\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33"+
|
||||
"\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67"+
|
||||
"\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65"+
|
||||
"i\66k\2m\2o\2q\2s\67u8w9y:{;}<\177=\u0081\2\3\2\5\4\2--//\5\2\13\f\17"+
|
||||
"\17\"\"\4\2\f\f\17\17\2\u01c5\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t"+
|
||||
"\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2"+
|
||||
"\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2"+
|
||||
"\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2"+
|
||||
"+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2"+
|
||||
"\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2"+
|
||||
"C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3"+
|
||||
"\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2"+
|
||||
"\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2"+
|
||||
"i\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3"+
|
||||
"\2\2\2\2\177\3\2\2\2\3\u0083\3\2\2\2\5\u0085\3\2\2\2\7\u008a\3\2\2\2\t"+
|
||||
"\u008f\3\2\2\2\13\u0094\3\2\2\2\r\u009a\3\2\2\2\17\u009f\3\2\2\2\21\u00a3"+
|
||||
"\3\2\2\2\23\u00a7\3\2\2\2\25\u00a9\3\2\2\2\27\u00ae\3\2\2\2\31\u00b3\3"+
|
||||
"\2\2\2\33\u00bd\3\2\2\2\35\u00c4\3\2\2\2\37\u00ca\3\2\2\2!\u00d3\3\2\2"+
|
||||
"\2#\u00d9\3\2\2\2%\u00e2\3\2\2\2\'\u00ec\3\2\2\2)\u00f5\3\2\2\2+\u00fc"+
|
||||
"\3\2\2\2-\u0103\3\2\2\2/\u0110\3\2\2\2\61\u0115\3\2\2\2\63\u011a\3\2\2"+
|
||||
"\2\65\u011f\3\2\2\2\67\u0123\3\2\2\29\u0128\3\2\2\2;\u012c\3\2\2\2=\u012f"+
|
||||
"\3\2\2\2?\u0136\3\2\2\2A\u013b\3\2\2\2C\u0140\3\2\2\2E\u0146\3\2\2\2G"+
|
||||
"\u014c\3\2\2\2I\u0152\3\2\2\2K\u0155\3\2\2\2M\u0157\3\2\2\2O\u0159\3\2"+
|
||||
"\2\2Q\u015b\3\2\2\2S\u015d\3\2\2\2U\u0160\3\2\2\2W\u0163\3\2\2\2Y\u0165"+
|
||||
"\3\2\2\2[\u0168\3\2\2\2]\u016a\3\2\2\2_\u016d\3\2\2\2a\u0170\3\2\2\2c"+
|
||||
"\u0175\3\2\2\2e\u0177\3\2\2\2g\u017f\3\2\2\2i\u0186\3\2\2\2k\u0191\3\2"+
|
||||
"\2\2m\u0193\3\2\2\2o\u0195\3\2\2\2q\u0197\3\2\2\2s\u0199\3\2\2\2u\u019b"+
|
||||
"\3\2\2\2w\u019d\3\2\2\2y\u019f\3\2\2\2{\u01a1\3\2\2\2}\u01a4\3\2\2\2\177"+
|
||||
"\u01aa\3\2\2\2\u0081\u01bb\3\2\2\2\u0083\u0084\7=\2\2\u0084\4\3\2\2\2"+
|
||||
"\u0085\u0086\7p\2\2\u0086\u0087\7w\2\2\u0087\u0088\7n\2\2\u0088\u0089"+
|
||||
"\7n\2\2\u0089\6\3\2\2\2\u008a\u008b\7u\2\2\u008b\u008c\7g\2\2\u008c\u008d"+
|
||||
"\7n\2\2\u008d\u008e\7h\2\2\u008e\b\3\2\2\2\u008f\u0090\7v\2\2\u0090\u0091"+
|
||||
"\7t\2\2\u0091\u0092\7w\2\2\u0092\u0093\7g\2\2\u0093\n\3\2\2\2\u0094\u0095"+
|
||||
"\7h\2\2\u0095\u0096\7c\2\2\u0096\u0097\7n\2\2\u0097\u0098\7u\2\2\u0098"+
|
||||
"\u0099\7g\2\2\u0099\f\3\2\2\2\u009a\u009b\7u\2\2\u009b\u009c\7s\2\2\u009c"+
|
||||
"\u009d\7t\2\2\u009d\u009e\7v\2\2\u009e\16\3\2\2\2\u009f\u00a0\7u\2\2\u00a0"+
|
||||
"\u00a1\7k\2\2\u00a1\u00a2\7p\2\2\u00a2\20\3\2\2\2\u00a3\u00a4\7e\2\2\u00a4"+
|
||||
"\u00a5\7q\2\2\u00a5\u00a6\7u\2\2\u00a6\22\3\2\2\2\u00a7\u00a8\7#\2\2\u00a8"+
|
||||
"\24\3\2\2\2\u00a9\u00aa\7i\2\2\u00aa\u00ab\7g\2\2\u00ab\u00ac\7v\2\2\u00ac"+
|
||||
"\u00ad\7z\2\2\u00ad\26\3\2\2\2\u00ae\u00af\7i\2\2\u00af\u00b0\7g\2\2\u00b0"+
|
||||
"\u00b1\7v\2\2\u00b1\u00b2\7{\2\2\u00b2\30\3\2\2\2\u00b3\u00b4\7i\2\2\u00b4"+
|
||||
"\u00b5\7g\2\2\u00b5\u00b6\7v\2\2\u00b6\u00b7\7t\2\2\u00b7\u00b8\7c\2\2"+
|
||||
"\u00b8\u00b9\7f\2\2\u00b9\u00ba\7k\2\2\u00ba\u00bb\7w\2\2\u00bb\u00bc"+
|
||||
"\7u\2\2\u00bc\32\3\2\2\2\u00bd\u00be\7i\2\2\u00be\u00bf\7g\2\2\u00bf\u00c0"+
|
||||
"\7v\2\2\u00c0\u00c1\7f\2\2\u00c1\u00c2\7k\2\2\u00c2\u00c3\7t\2\2\u00c3"+
|
||||
"\34\3\2\2\2\u00c4\u00c5\7i\2\2\u00c5\u00c6\7g\2\2\u00c6\u00c7\7v\2\2\u00c7"+
|
||||
"\u00c8\7c\2\2\u00c8\u00c9\7r\2\2\u00c9\36\3\2\2\2\u00ca\u00cb\7i\2\2\u00cb"+
|
||||
"\u00cc\7g\2\2\u00cc\u00cd\7v\2\2\u00cd\u00ce\7o\2\2\u00ce\u00cf\7c\2\2"+
|
||||
"\u00cf\u00d0\7z\2\2\u00d0\u00d1\7c\2\2\u00d1\u00d2\7r\2\2\u00d2 \3\2\2"+
|
||||
"\2\u00d3\u00d4\7i\2\2\u00d4\u00d5\7g\2\2\u00d5\u00d6\7v\2\2\u00d6\u00d7"+
|
||||
"\7j\2\2\u00d7\u00d8\7r\2\2\u00d8\"\3\2\2\2\u00d9\u00da\7u\2\2\u00da\u00db"+
|
||||
"\7c\2\2\u00db\u00dc\7o\2\2\u00dc\u00dd\7g\2\2\u00dd\u00de\7v\2\2\u00de"+
|
||||
"\u00df\7g\2\2\u00df\u00e0\7c\2\2\u00e0\u00e1\7o\2\2\u00e1$\3\2\2\2\u00e2"+
|
||||
"\u00e3\7u\2\2\u00e3\u00e4\7g\2\2\u00e4\u00e5\7c\2\2\u00e5\u00e6\7t\2\2"+
|
||||
"\u00e6\u00e7\7e\2\2\u00e7\u00e8\7j\2\2\u00e8\u00e9\7q\2\2\u00e9\u00ea"+
|
||||
"\7d\2\2\u00ea\u00eb\7l\2\2\u00eb&\3\2\2\2\u00ec\u00ed\7f\2\2\u00ed\u00ee"+
|
||||
"\7k\2\2\u00ee\u00ef\7u\2\2\u00ef\u00f0\7v\2\2\u00f0\u00f1\7c\2\2\u00f1"+
|
||||
"\u00f2\7p\2\2\u00f2\u00f3\7e\2\2\u00f3\u00f4\7g\2\2\u00f4(\3\2\2\2\u00f5"+
|
||||
"\u00f6\7k\2\2\u00f6\u00f7\7u\2\2\u00f7\u00f8\7y\2\2\u00f8\u00f9\7q\2\2"+
|
||||
"\u00f9\u00fa\7t\2\2\u00fa\u00fb\7o\2\2\u00fb*\3\2\2\2\u00fc\u00fd\7k\2"+
|
||||
"\2\u00fd\u00fe\7u\2\2\u00fe\u00ff\7h\2\2\u00ff\u0100\7q\2\2\u0100\u0101"+
|
||||
"\7q\2\2\u0101\u0102\7f\2\2\u0102,\3\2\2\2\u0103\u0104\7k\2\2\u0104\u0105"+
|
||||
"\7u\2\2\u0105\u0106\7r\2\2\u0106\u0107\7t\2\2\u0107\u0108\7q\2\2\u0108"+
|
||||
"\u0109\7l\2\2\u0109\u010a\7g\2\2\u010a\u010b\7e\2\2\u010b\u010c\7v\2\2"+
|
||||
"\u010c\u010d\7k\2\2\u010d\u010e\7n\2\2\u010e\u010f\7g\2\2\u010f.\3\2\2"+
|
||||
"\2\u0110\u0111\7v\2\2\u0111\u0112\7w\2\2\u0112\u0113\7t\2\2\u0113\u0114"+
|
||||
"\7p\2\2\u0114\60\3\2\2\2\u0115\u0116\7o\2\2\u0116\u0117\7q\2\2\u0117\u0118"+
|
||||
"\7x\2\2\u0118\u0119\7g\2\2\u0119\62\3\2\2\2\u011a\u011b\7l\2\2\u011b\u011c"+
|
||||
"\7w\2\2\u011c\u011d\7o\2\2\u011d\u011e\7r\2\2\u011e\64\3\2\2\2\u011f\u0120"+
|
||||
"\7g\2\2\u0120\u0121\7c\2\2\u0121\u0122\7v\2\2\u0122\66\3\2\2\2\u0123\u0124"+
|
||||
"\7h\2\2\u0124\u0125\7k\2\2\u0125\u0126\7t\2\2\u0126\u0127\7g\2\2\u0127"+
|
||||
"8\3\2\2\2\u0128\u0129\7f\2\2\u0129\u012a\7g\2\2\u012a\u012b\7h\2\2\u012b"+
|
||||
":\3\2\2\2\u012c\u012d\7k\2\2\u012d\u012e\7h\2\2\u012e<\3\2\2\2\u012f\u0130"+
|
||||
"\7k\2\2\u0130\u0131\7p\2\2\u0131\u0132\7x\2\2\u0132\u0133\7q\2\2\u0133"+
|
||||
"\u0134\7m\2\2\u0134\u0135\7g\2\2\u0135>\3\2\2\2\u0136\u0137\7v\2\2\u0137"+
|
||||
"\u0138\7j\2\2\u0138\u0139\7g\2\2\u0139\u013a\7p\2\2\u013a@\3\2\2\2\u013b"+
|
||||
"\u013c\7g\2\2\u013c\u013d\7n\2\2\u013d\u013e\7u\2\2\u013e\u013f\7g\2\2"+
|
||||
"\u013fB\3\2\2\2\u0140\u0141\7y\2\2\u0141\u0142\7j\2\2\u0142\u0143\7k\2"+
|
||||
"\2\u0143\u0144\7n\2\2\u0144\u0145\7g\2\2\u0145D\3\2\2\2\u0146\u0147\7"+
|
||||
"d\2\2\u0147\u0148\7t\2\2\u0148\u0149\7g\2\2\u0149\u014a\7c\2\2\u014a\u014b"+
|
||||
"\7m\2\2\u014bF\3\2\2\2\u014c\u014d\7r\2\2\u014d\u014e\7t\2\2\u014e\u014f"+
|
||||
"\7k\2\2\u014f\u0150\7p\2\2\u0150\u0151\7v\2\2\u0151H\3\2\2\2\u0152\u0153"+
|
||||
"\7<\2\2\u0153\u0154\7?\2\2\u0154J\3\2\2\2\u0155\u0156\7-\2\2\u0156L\3"+
|
||||
"\2\2\2\u0157\u0158\7/\2\2\u0158N\3\2\2\2\u0159\u015a\7,\2\2\u015aP\3\2"+
|
||||
"\2\2\u015b\u015c\7\61\2\2\u015cR\3\2\2\2\u015d\u015e\7(\2\2\u015e\u015f"+
|
||||
"\7(\2\2\u015fT\3\2\2\2\u0160\u0161\7~\2\2\u0161\u0162\7~\2\2\u0162V\3"+
|
||||
"\2\2\2\u0163\u0164\7>\2\2\u0164X\3\2\2\2\u0165\u0166\7>\2\2\u0166\u0167"+
|
||||
"\7?\2\2\u0167Z\3\2\2\2\u0168\u0169\7@\2\2\u0169\\\3\2\2\2\u016a\u016b"+
|
||||
"\7@\2\2\u016b\u016c\7?\2\2\u016c^\3\2\2\2\u016d\u016e\7?\2\2\u016e\u016f"+
|
||||
"\7?\2\2\u016f`\3\2\2\2\u0170\u0171\7#\2\2\u0171\u0172\7?\2\2\u0172b\3"+
|
||||
"\2\2\2\u0173\u0176\5g\64\2\u0174\u0176\5e\63\2\u0175\u0173\3\2\2\2\u0175"+
|
||||
"\u0174\3\2\2\2\u0176d\3\2\2\2\u0177\u0178\5g\64\2\u0178\u017a\7\60\2\2"+
|
||||
"\u0179\u017b\4\62;\2\u017a\u0179\3\2\2\2\u017b\u017c\3\2\2\2\u017c\u017a"+
|
||||
"\3\2\2\2\u017c\u017d\3\2\2\2\u017df\3\2\2\2\u017e\u0180\t\2\2\2\u017f"+
|
||||
"\u017e\3\2\2\2\u017f\u0180\3\2\2\2\u0180\u0182\3\2\2\2\u0181\u0183\4\62"+
|
||||
";\2\u0182\u0181\3\2\2\2\u0183\u0184\3\2\2\2\u0184\u0182\3\2\2\2\u0184"+
|
||||
"\u0185\3\2\2\2\u0185h\3\2\2\2\u0186\u018c\5k\66\2\u0187\u018b\5k\66\2"+
|
||||
"\u0188\u018b\5q9\2\u0189\u018b\7a\2\2\u018a\u0187\3\2\2\2\u018a\u0188"+
|
||||
"\3\2\2\2\u018a\u0189\3\2\2\2\u018b\u018e\3\2\2\2\u018c\u018a\3\2\2\2\u018c"+
|
||||
"\u018d\3\2\2\2\u018dj\3\2\2\2\u018e\u018c\3\2\2\2\u018f\u0192\5m\67\2"+
|
||||
"\u0190\u0192\5o8\2\u0191\u018f\3\2\2\2\u0191\u0190\3\2\2\2\u0192l\3\2"+
|
||||
"\2\2\u0193\u0194\4c|\2\u0194n\3\2\2\2\u0195\u0196\4C\\\2\u0196p\3\2\2"+
|
||||
"\2\u0197\u0198\4\62;\2\u0198r\3\2\2\2\u0199\u019a\7*\2\2\u019at\3\2\2"+
|
||||
"\2\u019b\u019c\7+\2\2\u019cv\3\2\2\2\u019d\u019e\7}\2\2\u019ex\3\2\2\2"+
|
||||
"\u019f\u01a0\7\177\2\2\u01a0z\3\2\2\2\u01a1\u01a2\7<\2\2\u01a2|\3\2\2"+
|
||||
"\2\u01a3\u01a5\t\3\2\2\u01a4\u01a3\3\2\2\2\u01a5\u01a6\3\2\2\2\u01a6\u01a4"+
|
||||
"\3\2\2\2\u01a6\u01a7\3\2\2\2\u01a7\u01a8\3\2\2\2\u01a8\u01a9\b?\2\2\u01a9"+
|
||||
"~\3\2\2\2\u01aa\u01ab\7\61\2\2\u01ab\u01ac\7\61\2\2\u01ac\u01b0\3\2\2"+
|
||||
"\2\u01ad\u01af\n\4\2\2\u01ae\u01ad\3\2\2\2\u01af\u01b2\3\2\2\2\u01b0\u01ae"+
|
||||
"\3\2\2\2\u01b0\u01b1\3\2\2\2\u01b1\u01b3\3\2\2\2\u01b2\u01b0\3\2\2\2\u01b3"+
|
||||
"\u01b4\5\u0081A\2\u01b4\u01b5\3\2\2\2\u01b5\u01b6\b@\2\2\u01b6\u0080\3"+
|
||||
"\2\2\2\u01b7\u01b9\7\17\2\2\u01b8\u01b7\3\2\2\2\u01b8\u01b9\3\2\2\2\u01b9"+
|
||||
"\u01ba\3\2\2\2\u01ba\u01bc\7\f\2\2\u01bb\u01b8\3\2\2\2\u01bc\u01bd\3\2"+
|
||||
"\2\2\u01bd\u01bb\3\2\2\2\u01bd\u01be\3\2\2\2\u01be\u0082\3\2\2\2\16\2"+
|
||||
"\u0175\u017c\u017f\u0184\u018a\u018c\u0191\u01a6\u01b0\u01b8\u01bd\3\b"+
|
||||
"\2\2";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
|
||||
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
|
||||
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,112 @@
|
||||
T__0=1
|
||||
NULL=2
|
||||
SELF=3
|
||||
TRUE=4
|
||||
FALSE=5
|
||||
SQRT=6
|
||||
SIN=7
|
||||
COS=8
|
||||
NOT=9
|
||||
GETX=10
|
||||
GETY=11
|
||||
GETRADIUS=12
|
||||
GETDIR=13
|
||||
GETAP=14
|
||||
GETMAXAP=15
|
||||
GETHP=16
|
||||
SAMETEAM=17
|
||||
SEARCHOBJ=18
|
||||
DISTANCE=19
|
||||
ISWORM=20
|
||||
ISFOOD=21
|
||||
ISPROJECTILE=22
|
||||
TURN=23
|
||||
MOVE=24
|
||||
JUMP=25
|
||||
EAT=26
|
||||
FIRE=27
|
||||
DEF=28
|
||||
IF=29
|
||||
INVOKE=30
|
||||
THEN=31
|
||||
ELSE=32
|
||||
WHILE=33
|
||||
BREAK=34
|
||||
PRINT=35
|
||||
ASSIGN=36
|
||||
ADD=37
|
||||
SUB=38
|
||||
MUL=39
|
||||
DIV=40
|
||||
AND=41
|
||||
OR=42
|
||||
LT=43
|
||||
LTE=44
|
||||
GT=45
|
||||
GTE=46
|
||||
EQ=47
|
||||
NEQ=48
|
||||
NUMBER=49
|
||||
FLOAT=50
|
||||
INTEGER=51
|
||||
IDENTIFIER=52
|
||||
LEFT_PAREN=53
|
||||
RIGHT_PAREN=54
|
||||
LEFT_BRACE=55
|
||||
RIGHT_BRACE=56
|
||||
COLON=57
|
||||
WHITESPACE=58
|
||||
SINGLE_COMMENT=59
|
||||
';'=1
|
||||
'null'=2
|
||||
'self'=3
|
||||
'true'=4
|
||||
'false'=5
|
||||
'sqrt'=6
|
||||
'sin'=7
|
||||
'cos'=8
|
||||
'!'=9
|
||||
'getx'=10
|
||||
'gety'=11
|
||||
'getradius'=12
|
||||
'getdir'=13
|
||||
'getap'=14
|
||||
'getmaxap'=15
|
||||
'gethp'=16
|
||||
'sameteam'=17
|
||||
'searchobj'=18
|
||||
'distance'=19
|
||||
'isworm'=20
|
||||
'isfood'=21
|
||||
'isprojectile'=22
|
||||
'turn'=23
|
||||
'move'=24
|
||||
'jump'=25
|
||||
'eat'=26
|
||||
'fire'=27
|
||||
'def'=28
|
||||
'if'=29
|
||||
'invoke'=30
|
||||
'then'=31
|
||||
'else'=32
|
||||
'while'=33
|
||||
'break'=34
|
||||
'print'=35
|
||||
':='=36
|
||||
'+'=37
|
||||
'-'=38
|
||||
'*'=39
|
||||
'/'=40
|
||||
'&&'=41
|
||||
'||'=42
|
||||
'<'=43
|
||||
'<='=44
|
||||
'>'=45
|
||||
'>='=46
|
||||
'=='=47
|
||||
'!='=48
|
||||
'('=53
|
||||
')'=54
|
||||
'{'=55
|
||||
'}'=56
|
||||
':'=57
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,306 @@
|
||||
// Generated from WormsProgram.g4 by ANTLR 4.7.1
|
||||
|
||||
package worms.programs.internal.parser.generated;
|
||||
|
||||
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
|
||||
|
||||
/**
|
||||
* This interface defines a complete generic visitor for a parse tree produced
|
||||
* by {@link WormsProgramParser}.
|
||||
*
|
||||
* @param <T> The return type of the visit operation. Use {@link Void} for
|
||||
* operations with no return type.
|
||||
*/
|
||||
public interface WormsProgramVisitor<T> extends ParseTreeVisitor<T> {
|
||||
/**
|
||||
* Visit a parse tree produced by {@link WormsProgramParser#program}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitProgram(WormsProgramParser.ProgramContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link WormsProgramParser#proceduredef}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitProceduredef(WormsProgramParser.ProceduredefContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link WormsProgramParser#statement}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitStatement(WormsProgramParser.StatementContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link WormsProgramParser#assignmentStatement}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitAssignmentStatement(WormsProgramParser.AssignmentStatementContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link WormsProgramParser#whileStatement}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitWhileStatement(WormsProgramParser.WhileStatementContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link WormsProgramParser#ifStatement}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitIfStatement(WormsProgramParser.IfStatementContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link WormsProgramParser#printStatement}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitPrintStatement(WormsProgramParser.PrintStatementContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link WormsProgramParser#sequenceStatement}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitSequenceStatement(WormsProgramParser.SequenceStatementContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link WormsProgramParser#invokeStatement}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitInvokeStatement(WormsProgramParser.InvokeStatementContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by {@link WormsProgramParser#breakStatement}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitBreakStatement(WormsProgramParser.BreakStatementContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code turnAction}
|
||||
* labeled alternative in {@link WormsProgramParser#actionStatement}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitTurnAction(WormsProgramParser.TurnActionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code moveAction}
|
||||
* labeled alternative in {@link WormsProgramParser#actionStatement}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitMoveAction(WormsProgramParser.MoveActionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code jumpAction}
|
||||
* labeled alternative in {@link WormsProgramParser#actionStatement}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitJumpAction(WormsProgramParser.JumpActionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code eatAction}
|
||||
* labeled alternative in {@link WormsProgramParser#actionStatement}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitEatAction(WormsProgramParser.EatActionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code fireAction}
|
||||
* labeled alternative in {@link WormsProgramParser#actionStatement}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitFireAction(WormsProgramParser.FireActionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code distanceExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitDistanceExpression(WormsProgramParser.DistanceExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code cosExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitCosExpression(WormsProgramParser.CosExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code getYExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGetYExpression(WormsProgramParser.GetYExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code andOrExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitAndOrExpression(WormsProgramParser.AndOrExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code isWormExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitIsWormExpression(WormsProgramParser.IsWormExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code notExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitNotExpression(WormsProgramParser.NotExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code comparisonExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitComparisonExpression(WormsProgramParser.ComparisonExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code parenExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitParenExpression(WormsProgramParser.ParenExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code getRadiusExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGetRadiusExpression(WormsProgramParser.GetRadiusExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code trueLiteralExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitTrueLiteralExpression(WormsProgramParser.TrueLiteralExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code nullExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitNullExpression(WormsProgramParser.NullExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code sqrtExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitSqrtExpression(WormsProgramParser.SqrtExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code sinExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitSinExpression(WormsProgramParser.SinExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code sameTeamExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitSameTeamExpression(WormsProgramParser.SameTeamExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code isProjectileExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitIsProjectileExpression(WormsProgramParser.IsProjectileExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code isFoodExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitIsFoodExpression(WormsProgramParser.IsFoodExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code constantExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitConstantExpression(WormsProgramParser.ConstantExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code searchObjExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitSearchObjExpression(WormsProgramParser.SearchObjExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code getXExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGetXExpression(WormsProgramParser.GetXExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code readVariableExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitReadVariableExpression(WormsProgramParser.ReadVariableExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code mulDivExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitMulDivExpression(WormsProgramParser.MulDivExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code getDirectionExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGetDirectionExpression(WormsProgramParser.GetDirectionExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code selfExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitSelfExpression(WormsProgramParser.SelfExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code getHPExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGetHPExpression(WormsProgramParser.GetHPExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code addSubExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitAddSubExpression(WormsProgramParser.AddSubExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code getMaxAPExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGetMaxAPExpression(WormsProgramParser.GetMaxAPExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code getAPExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitGetAPExpression(WormsProgramParser.GetAPExpressionContext ctx);
|
||||
/**
|
||||
* Visit a parse tree produced by the {@code falseLiteralExpression}
|
||||
* labeled alternative in {@link WormsProgramParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
T visitFalseLiteralExpression(WormsProgramParser.FalseLiteralExpressionContext ctx);
|
||||
}
|
0
OGP1718-Worms/src-provided/worms/util/ModelException.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/util/ModelException.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/util/MustNotImplementException.java
Normal file → Executable file
0
OGP1718-Worms/src-provided/worms/util/MustNotImplementException.java
Normal file → Executable file
0
OGP1718-Worms/tests/worms/model/PartialPart2FacadeTest.java
Normal file → Executable file
0
OGP1718-Worms/tests/worms/model/PartialPart2FacadeTest.java
Normal file → Executable file
42
OGP1718-Worms/tests/worms/model/PartialPart3FacadeTest.java
Executable file
42
OGP1718-Worms/tests/worms/model/PartialPart3FacadeTest.java
Executable file
@@ -0,0 +1,42 @@
|
||||
package worms.model;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import worms.facade.Facade;
|
||||
import worms.facade.IFacade;
|
||||
import worms.internal.gui.game.IActionHandler;
|
||||
import worms.model.Worm;
|
||||
import worms.programs.IProgramFactory;
|
||||
import worms.programs.ProgramParser;
|
||||
|
||||
public class PartialPart3FacadeTest {
|
||||
|
||||
private static final double EPS = 1e-4;
|
||||
|
||||
private IFacade facade;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
facade = new Facade();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testProgram() {
|
||||
World world = facade.createWorld(100.0, 100.0, new boolean[][] { {true}, {false} });
|
||||
IProgramFactory<?, ?, ?, ? extends Program> programFactory = facade.createProgramFactory();
|
||||
|
||||
Program program = ProgramParser.parseProgramFromString("x := 0; while x < 1.5: { x := x + 0.1; } turn x;", programFactory);
|
||||
Worm worm = facade.createWorm(world, new double[] { 50.0, 50.51 }, 0, 0.5, "TestWorm", null);
|
||||
IActionHandler handler = new SimpleActionHandler(facade);
|
||||
facade.loadProgramOnWorm(worm, program, handler);
|
||||
double oldOrientation = facade.getOrientation(worm);
|
||||
facade.startGame(world); // this will run the program
|
||||
double newOrientation = facade.getOrientation(worm);
|
||||
assertEquals(oldOrientation + 1.5, newOrientation, EPS);
|
||||
}
|
||||
|
||||
}
|
95
OGP1718-Worms/tests/worms/model/SimpleActionHandler.java
Executable file
95
OGP1718-Worms/tests/worms/model/SimpleActionHandler.java
Executable file
@@ -0,0 +1,95 @@
|
||||
package worms.model;
|
||||
|
||||
import worms.facade.IFacade;
|
||||
import worms.internal.gui.GUIConstants;
|
||||
import worms.internal.gui.game.IActionHandler;
|
||||
import worms.util.ModelException;
|
||||
|
||||
/**
|
||||
* A simple action handler that just calls the necessary methods on the facade.
|
||||
* Useful for writing tests; there's no other reason to use this.
|
||||
*/
|
||||
public class SimpleActionHandler implements IActionHandler {
|
||||
|
||||
private final IFacade facade;
|
||||
|
||||
public SimpleActionHandler(IFacade facade) {
|
||||
this.facade = facade;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean turn(Worm worm, double angle) {
|
||||
try {
|
||||
facade.turn(worm, angle);
|
||||
return true;
|
||||
} catch (ModelException e) {
|
||||
if (e.getCause() instanceof RuntimeException) {
|
||||
throw (RuntimeException) e.getCause();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void print(String message) {
|
||||
System.out.println(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean move(Worm worm) {
|
||||
try {
|
||||
facade.move(worm);
|
||||
if (facade.canFall(worm)) {
|
||||
facade.fall(worm);
|
||||
}
|
||||
return true;
|
||||
} catch (ModelException e) {
|
||||
if (e.getCause() instanceof RuntimeException) {
|
||||
throw (RuntimeException) e.getCause();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean jump(Worm worm) {
|
||||
try {
|
||||
facade.jump(worm, GUIConstants.JUMP_TIME_STEP);
|
||||
if (facade.canFall(worm)) {
|
||||
facade.fall(worm);
|
||||
}
|
||||
return true;
|
||||
} catch (ModelException e) {
|
||||
if (e.getCause() instanceof RuntimeException) {
|
||||
throw (RuntimeException) e.getCause();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fire(Worm worm) {
|
||||
try {
|
||||
facade.fire(worm);
|
||||
return true;
|
||||
} catch (ModelException e) {
|
||||
if (e.getCause() instanceof RuntimeException) {
|
||||
throw (RuntimeException) e.getCause();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eat(Worm worm) {
|
||||
try {
|
||||
facade.eat(worm);
|
||||
return true;
|
||||
} catch (ModelException e) {
|
||||
if (e.getCause() instanceof RuntimeException) {
|
||||
throw (RuntimeException) e.getCause();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user