diff --git a/src/main/java/expression/Addition.java b/src/main/java/expression/Addition.java index a863a68..893f72e 100644 --- a/src/main/java/expression/Addition.java +++ b/src/main/java/expression/Addition.java @@ -6,11 +6,14 @@ package expression; /*! -Eine `Addition` besteht aus einer `leftHandSide` und einer `rightHandSide`, die addiert werden sollen. +An `Addition` consists of a `leftHandSide` and a `rightHandSide` expression, which are supposed to be added. + +For example -Zum Beispiel new Addition(new Identifier("x"), new Int(2)) -repräsentiert den Ausdruck + +represents the code + x + 2 */ public class Addition extends Expression { @@ -22,12 +25,13 @@ public class Addition extends Expression { this.rightHandSide = rightHandSide; } -/*!- Hilfsmethoden */ + /*!- String serialization */ @Override public String toString() { return "(" + leftHandSide + " + " + rightHandSide + ")"; } + /*!- Generated equals implementation */ @Override public boolean equals(Object o) { if (this == o) return true; @@ -39,11 +43,4 @@ public class Addition extends Expression { return rightHandSide.equals(addition.rightHandSide); } - - @Override - public int hashCode() { - int result = leftHandSide.hashCode(); - result = 31 * result + rightHandSide.hashCode(); - return result; - } } diff --git a/src/main/java/expression/Expression.java b/src/main/java/expression/Expression.java index 9e91fa8..ebabd60 100644 --- a/src/main/java/expression/Expression.java +++ b/src/main/java/expression/Expression.java @@ -1,4 +1,9 @@ +/*!! Expression*/ + +/*! # Expression*/ + +/*!- Header */ package expression; -abstract public class Expression { -} +/*! `Expression` is the common abstract class for Expressions that can be evaluated using the `Evaluator`. */ +abstract public class Expression { } diff --git a/src/main/java/expression/Identifier.java b/src/main/java/expression/Identifier.java index d3b977b..40f2b71 100644 --- a/src/main/java/expression/Identifier.java +++ b/src/main/java/expression/Identifier.java @@ -1,30 +1,34 @@ -package expression; +/*!! Expression*/ -public class Identifier extends Expression { - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; +/*! # Identifier*/ - Identifier that = (Identifier) o; +/*! Header*/ +package expression; - return name.equals(that.name); +/*! An `Identifier` consists only of the `name` of the identifier. This class is only needed as a wrapper which allows +us to use an identifier as an expression. */ +public class Identifier extends Expression { + public final String name; + public Identifier(String name) { + this.name = name; } + /*!- String serialization */ @Override public String toString() { return name; } + /*!- generated equals implementation */ @Override - public int hashCode() { - return name.hashCode(); - } + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; - public final String name; + Identifier that = (Identifier) o; + + return name.equals(that.name); - public Identifier(String name) { - this.name = name; } } diff --git a/src/main/java/expression/Int.java b/src/main/java/expression/Int.java index 6932c75..dcd9bd1 100644 --- a/src/main/java/expression/Int.java +++ b/src/main/java/expression/Int.java @@ -1,5 +1,14 @@ +/*!! Expression*/ + +/*! # Int */ + +/*!- Header */ package expression; +/*! +An `Int` consists only of its `value`. This class is only needed as a wrapper which allows +us to use an integer as an expression. +*/ public class Int extends Expression { public final int value; @@ -7,6 +16,13 @@ public class Int extends Expression { this.value = value; } + /*!- String serialization */ + @Override + public String toString() { + return Integer.toString(value); + } + + /*!- generated equals implementation */ @Override public boolean equals(Object o) { if (this == o) return true; @@ -15,16 +31,5 @@ public class Int extends Expression { Int integer = (Int) o; return value == integer.value; - - } - - @Override - public String toString() { - return Integer.toString(value); - } - - @Override - public int hashCode() { - return value; } } diff --git a/src/main/java/expression/Subtraction.java b/src/main/java/expression/Subtraction.java index 52d4571..0383c61 100644 --- a/src/main/java/expression/Subtraction.java +++ b/src/main/java/expression/Subtraction.java @@ -1,9 +1,37 @@ +/*!! Expression */ + +/*! # Subtraction */ + +/*!- Header */ package expression; +/*! +A `Subtraction` consists of a `leftHandSide` and a `rightHandSide` expression, which are supposed to be subtracted. + +For example + + new Subtraction(new Identifier("x"), new Int(2)) + +represents the code + + x - 2 +*/ public class Subtraction extends Expression { public final Expression leftHandSide; public final Expression rightHandSide; + public Subtraction(Expression leftHandSide, Expression rightHandSide) { + this.leftHandSide = leftHandSide; + this.rightHandSide = rightHandSide; + } + + /*!- String serialization */ + @Override + public String toString() { + return "(" + leftHandSide + " - " + rightHandSide + ")"; + } + + /*!- generated equals implementation */ @Override public boolean equals(Object o) { if (this == o) return true; @@ -15,21 +43,4 @@ public class Subtraction extends Expression { return rightHandSide.equals(that.rightHandSide); } - - @Override - public String toString() { - return "(" + leftHandSide + " - " + rightHandSide + ")"; - } - - @Override - public int hashCode() { - int result = leftHandSide.hashCode(); - result = 31 * result + rightHandSide.hashCode(); - return result; - } - - public Subtraction(Expression leftHandSide, Expression rightHandSide) { - this.leftHandSide = leftHandSide; - this.rightHandSide = rightHandSide; - } } diff --git a/src/main/java/parser/Parser.java b/src/main/java/parser/Parser.java index bc44991..7da6534 100644 --- a/src/main/java/parser/Parser.java +++ b/src/main/java/parser/Parser.java @@ -1,7 +1,12 @@ /*!! Parser */ /*! + # Parser -Dieser [rekursiv absteigende Parser](https://de.wikipedia.org/wiki/Rekursiver_Abstieg) versteht sehr einfache While-Programme, die folgender Grammatik in [EBNF](https://de.wikipedia.org/wiki/Erweiterte_Backus-Naur-Form) genügen: + +In order to parse simple while programs we use a +[Recursive descent parser](https://en.wikipedia.org/wiki/Recursive_descent_parser). The syntax of our while programs +are defined by the following grammar in +[Extended Backus-Naur Form (EBNF)](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form): Prog = Id ":=" Expr | Prog ";" Prog | @@ -12,10 +17,10 @@ Dieser [rekursiv absteigende Parser](https://de.wikipedia.org/wiki/Rekursiver_Ab Atom Atom = Id | Num | "(" Expr ")" -Dabei kann `Num` direkt zu einer beliebigen ganzen Zahl und `Id` direkt zu einem beliebigen Bezeichner aus den Zeichen -`a` bis `z` abgeleitet werden. +The non-terminal `Num` can be derived into an arbitrary integer. `Id` can be derived into an arbitrary identifier +consisting of the lower case characters from `a` to `z`. -Der Parser nimmt einen String mit dem Quelltext entgegen und erzeugt daraus ein `Program`. +Our parser takes the source code as argument and returns a `Program` object. */ /*!- Header */ @@ -29,26 +34,27 @@ import java.util.ArrayList; import java.util.List; /*! -Die Klasse `Parser` implementiert den Parser. Sie wird verwendet, indem dem Konstruktor der zu parsende Quelltext -übergeben wird. Anschließend kann die Methide `parse` aufgerufen werden, die das geparste `Program` zurückgibt. +`Parser` provides a constructor which takes the source code as argument. The created object provides the method +`parse` which returns the parsed `Program` object. Parser parser = new Parser("a := 1"); Program program = parser.parse(); */ public class Parser { -/*! -Die Instanzvariable `input` hält den zu parsenden Quelltext und in `position` steht die aktuelle Position des Parsers. -Alle folgenden Methoden betrachten den Quelltext jeweils ab der aktuellen Position und erhöhen diese, wenn Zeichen -des Quelltextes geparsed wurden. -*/ + /*! + The instance variable `input` contains the source code that should be parsed and `position` contains the current + position of the parser in the `input` string. The following parsing methods each consider the characters of the + `input` starting at `position`, e.g. `input.charAt(position)`. After consuming characters of the input the methods + increment the `position`. + */ int position; - String input; + final String input; public Parser(String input) { this.input = input; } - + public Program parse() { position = 0; Program program = program(); diff --git a/src/main/java/program/Assignment.java b/src/main/java/program/Assignment.java index f0a077f..4bd2038 100644 --- a/src/main/java/program/Assignment.java +++ b/src/main/java/program/Assignment.java @@ -1,38 +1,49 @@ +/*!! Program*/ + +/*! # Program */ + +/*!- Header */ + package program; import expression.Expression; import expression.Identifier; -public class Assignment extends Program { - public final Identifier identifier; - public final Expression expression; +/*! An `Assignment` consists of an `identifier` and an `expression` which should be evaluated and the result stored +in the variable named by the identifier. - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; +For example - Assignment that = (Assignment) o; + new Assignment(new Identifier("x"), new Number(5)) - if (!identifier.equals(that.identifier)) return false; - return expression.equals(that.expression); +represents the code + x := 5 +*/ +public class Assignment extends Program { + public final Identifier identifier; + public final Expression expression; + + public Assignment(Identifier identifier, Expression expression) { + this.identifier = identifier; + this.expression = expression; } + /*!- String serialization */ @Override public String toString() { return identifier + " := " + expression; } + /*!- generated equals method*/ @Override - public int hashCode() { - int result = identifier.hashCode(); - result = 31 * result + expression.hashCode(); - return result; - } + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; - public Assignment(Identifier identifier, Expression expression) { - this.identifier = identifier; - this.expression = expression; + Assignment that = (Assignment) o; + + if (!identifier.equals(that.identifier)) return false; + return expression.equals(that.expression); } } diff --git a/src/main/java/program/Composition.java b/src/main/java/program/Composition.java index cc11f8a..fc06491 100644 --- a/src/main/java/program/Composition.java +++ b/src/main/java/program/Composition.java @@ -1,35 +1,36 @@ +/*!! Program*/ + +/*! # Composition*/ + +/*!- Header*/ package program; +/*! A `Composition` combines two programs (`first` and `second`) with the intended semantics of sequential +composition. */ public class Composition extends Program { public final Program first; public final Program second; - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Composition that = (Composition) o; - - if (!first.equals(that.first)) return false; - return second.equals(that.second); - + public Composition(Program first, Program second) { + this.first = first; + this.second = second; } + /*!- String serialization */ @Override public String toString() { return first + " ; " + second; } + /*!- generated equals implementation */ @Override - public int hashCode() { - int result = first.hashCode(); - result = 31 * result + second.hashCode(); - return result; - } + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; - public Composition(Program first, Program second) { - this.first = first; - this.second = second; + Composition that = (Composition) o; + + if (!first.equals(that.first)) return false; + return second.equals(that.second); } } diff --git a/src/main/java/program/Conditional.java b/src/main/java/program/Conditional.java index 4202622..8f7dfb2 100644 --- a/src/main/java/program/Conditional.java +++ b/src/main/java/program/Conditional.java @@ -1,12 +1,26 @@ +/*!! Program*/ + +/*! # Conditional*/ + +/*!- Header*/ package program; import expression.Expression; +/*! A `Conditional` consists of the `condition` expression and the two programs `thenCase` and `elseCase` with the +intended semantics of execution the `elseCase` if the `expression` evaluates to 0 and the `thenCase` otherwise. */ public class Conditional extends Program { public final Expression condition; public final Program thenCase; public final Program elseCase; + public Conditional(Expression condition, Program thenCase, Program elseCase) { + this.condition = condition; + this.thenCase = thenCase; + this.elseCase = elseCase; + } + + /*!- generated equals implementation */ @Override public boolean equals(Object o) { if (this == o) return true; @@ -20,22 +34,9 @@ public class Conditional extends Program { } + /*!- String serialization*/ @Override public String toString() { return "if (" + condition + ") then { " + thenCase + " } else { " + elseCase + " }"; } - - @Override - public int hashCode() { - int result = condition.hashCode(); - result = 31 * result + thenCase.hashCode(); - result = 31 * result + elseCase.hashCode(); - return result; - } - - public Conditional(Expression condition, Program thenCase, Program elseCase) { - this.condition = condition; - this.thenCase = thenCase; - this.elseCase = elseCase; - } } diff --git a/src/main/java/program/Loop.java b/src/main/java/program/Loop.java index bb1691b..f21f3ce 100644 --- a/src/main/java/program/Loop.java +++ b/src/main/java/program/Loop.java @@ -1,7 +1,14 @@ +/*!! Program*/ + +/*! # Loop */ + +/*!- Header*/ package program; import expression.Expression; +/*! A `Loop` consists of a `condition` and a `program` with the intended semantics of execution the `program` while +the `condition` evaluates to a non-zero value. */ public class Loop extends Program { public final Expression condition; public final Program program; @@ -11,6 +18,13 @@ public class Loop extends Program { this.program = program; } + /*!- String serialization */ + @Override + public String toString() { + return "while (" + condition + ") { " + program + " }"; + } + + /*!- generated equals implementation */ @Override public boolean equals(Object o) { if (this == o) return true; @@ -22,16 +36,4 @@ public class Loop extends Program { return program.equals(loop.program); } - - @Override - public String toString() { - return "while (" + condition + ") { " + program + " }"; - } - - @Override - public int hashCode() { - int result = condition.hashCode(); - result = 31 * result + program.hashCode(); - return result; - } } diff --git a/src/main/java/program/Program.java b/src/main/java/program/Program.java index c7969be..cd45b44 100644 --- a/src/main/java/program/Program.java +++ b/src/main/java/program/Program.java @@ -1,4 +1,9 @@ +/*!! Program*/ + +/*! # Program */ + +/*!- Header*/ package program; -abstract public class Program { -} +/*! `Program` is the abstract common class for programs that can be exeuted using the `Interpreter`. */ +abstract public class Program { }