Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions homework-g597-vasilyev/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
</parent>
<modelVersion>4.0.0</modelVersion>

<properties>
<spring.boot.version>1.4.2.RELEASE</spring.boot.version>
</properties>

<artifactId>homework-g597-vasilyev</artifactId>
<dependencies>
<dependency>
Expand All @@ -22,5 +26,42 @@
<version>1.0.0</version>
<scope>test</scope>
</dependency>

<!-- Spring dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.193</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package ru.mipt.java2016.homework.g597.vasilyev.task1;

import ru.mipt.java2016.homework.base.task1.ParsingException;

import java.util.Stack;
import java.util.function.Function;

/**
* Created by mizabrik on 21.12.16.
*/
public class BuiltinCommand implements Command {
private final Function<Double[], Double> function;
private final int valency;

public BuiltinCommand(Function<Double[], Double> function, int valency) {
this.function = function;
this.valency = valency;
}

@Override
public void apply(Stack<Double> stack) throws ParsingException {
Double[] args = new Double[valency];

for (int i = valency - 1; i >= 0; --i) {
args[i] = stack.pop();
}

stack.push(function.apply(args));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package ru.mipt.java2016.homework.g597.vasilyev.task1;

import ru.mipt.java2016.homework.base.task1.ParsingException;

import java.util.Stack;

/**
* Created by mizabrik on 19.12.16.
*/
public interface Command {
void apply(Stack<Double> stack) throws ParsingException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package ru.mipt.java2016.homework.g597.vasilyev.task1;

import ru.mipt.java2016.homework.base.task1.ParsingException;

import java.util.Map;

/**
* Created by mizabrik on 18.12.16.
*/
public class ExpressionTokenizer {
public enum TokenType {
OPENING_BRACKET, CLOSING_BRACKET, NUMBER, IDENTIFIER, OPERATOR, COMMA
}

private final String expression;
private final Map<Character, Operator> operators;
private int position = 0;

public ExpressionTokenizer(String expression, Map<Character, Operator> operators) {
this.expression = expression;
this.operators = operators;
skipSpaces();
}

public TokenType peekNextType() throws ParsingException {
if (hasChar()) {
char c = peekChar();

if (Character.isDigit(c)) {
return TokenType.NUMBER;
} else if (Character.isAlphabetic(c)) {
return TokenType.IDENTIFIER;
} else if (c == '(') {
return TokenType.OPENING_BRACKET;
} else if (c == ')') {
return TokenType.CLOSING_BRACKET;
} else if (operators.containsKey(c)) {
return TokenType.OPERATOR;
} else if (c == ',') {
return TokenType.COMMA;
} else {
throw new ParsingException("Unexpected character " + c);
}
} else {
return null;
}
}

public double nextNumber() throws ParsingException {
if (peekNextType() != TokenType.NUMBER) {
throw new ParsingException("No number at postition " + Integer.toString(position));
}

double number = 0.0;

while (hasDigit()) {
number *= 10;
number += Character.getNumericValue(nextChar());
}

if (hasChar() && peekChar() == '.') {
nextChar();

double fraction = 1;
while (hasDigit()) {
fraction /= 10;
number += Character.getNumericValue(nextChar()) * fraction;
}
}

skipSpaces();
return number;
}

public String nextIdentifier() throws ParsingException {
if (peekNextType() != TokenType.IDENTIFIER) {
throw new ParsingException("No identifier at position " + Integer.toString(position));
}

StringBuilder builder = new StringBuilder();
while (hasAlphanumeric()) {
builder.append(nextChar());
}

skipSpaces();
return builder.toString();
}

public char nextBracket() throws ParsingException {
if (peekNextType() != TokenType.OPENING_BRACKET && peekNextType() != TokenType.CLOSING_BRACKET) {
throw new ParsingException("No bracket at position " + Integer.toString(position));
}

char bracket = nextChar();

skipSpaces();
return bracket;
}

public Operator nextOperator() throws ParsingException {
if (peekNextType() != TokenType.OPERATOR) {
throw new ParsingException("No operator at position " + Integer.toString(position));
}

Operator operator = operators.get(nextChar());

skipSpaces();
return operator;
}

public char nextComma() throws ParsingException {
if (peekNextType() != TokenType.COMMA) {
throw new ParsingException("No comma at position " + Integer.toString(position));
}

char comma = nextChar();

skipSpaces();
return comma;
}


private boolean hasChar() {
return position < expression.length();
}

private boolean hasAlphanumeric() {
return hasChar() && (Character.isAlphabetic(peekChar()) || hasDigit());
}

private boolean hasDigit() {
return hasChar() && Character.isDigit(peekChar());
}

private char nextChar() {
return expression.charAt(position++);
}

private char peekChar() {
return expression.charAt(position);
}

private void skipSpaces() {
while (hasChar() && Character.isWhitespace(peekChar())) {
nextChar();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ru.mipt.java2016.homework.g597.vasilyev.task1;

import ru.mipt.java2016.homework.base.task1.Calculator;
import ru.mipt.java2016.homework.base.task1.ParsingException;

/**
* Created by mizabrik on 21.12.16.
*/
public interface ExtendableCalculator extends Calculator {
boolean supportsFunction(String name);

double calculate(String expression, Scope scope) throws ParsingException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package ru.mipt.java2016.homework.g597.vasilyev.task1;

import ru.mipt.java2016.homework.base.task1.ParsingException;

import java.util.Stack;

/**
* Created by mizabrik on 21.12.16.
*/
public class FunctionCommand implements Command {
private Command command;

public FunctionCommand(Command command) {
this.command = command;
}

@Override
public void apply(Stack<Double> stack) throws ParsingException {
command.apply(stack);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package ru.mipt.java2016.homework.g597.vasilyev.task1;

import java.util.Map;

/**
* Created by mizabrik on 21.12.16.
*/
public class MapScope implements Scope {
private Map<String, Command> map;

public MapScope(Map<String, Command> map) {
this.map = map;
}

@Override
public Command getCommand(String name) {
return map.get(name);
}

@Override
public boolean hasCommand(String name) {
return map.containsKey(name);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package ru.mipt.java2016.homework.g597.vasilyev.task1;

import java.util.Stack;
import ru.mipt.java2016.homework.base.task1.ParsingException;

import java.util.Stack;

/**
* Created by mizabrik on 10.10.16.
* Arithmetic operator class.
*/
enum Operator {
enum Operator implements Command {
ADD(2, 2, true),
SUBTRACT(2, 2, true),
MULTIPLY(1, 2, true),
Expand All @@ -25,7 +26,8 @@ enum Operator {
}

// Apply operator to stack
void apply(Stack<Double> numbers) throws ParsingException {
@Override
public void apply(Stack<Double> numbers) throws ParsingException {
// Too few arguments
if (numbers.size() < valency) {
throw new ParsingException("Too few operands");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package ru.mipt.java2016.homework.g597.vasilyev.task1;

import java.util.HashMap;
import java.util.Map;

/**
* Created by mizabrik on 21.12.16.
*/
public class OverridingScope implements Scope {
private Scope origin;
private Map<String, Command> overrides = new HashMap<>();

public OverridingScope(Scope origin) {
this.origin = origin;
}

public void addOverride(String name, Command command) {
overrides.put(name, command);
}

@Override
public Command getCommand(String name) {
if (overrides.containsKey(name)) {
return overrides.get(name);
} else {
return origin.getCommand(name);
}
}

@Override
public boolean hasCommand(String name) {
return overrides.containsKey(name) || origin.hasCommand(name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package ru.mipt.java2016.homework.g597.vasilyev.task1;

import ru.mipt.java2016.homework.base.task1.ParsingException;

import java.util.Stack;

/**
* Created by mizabrik on 19.12.16.
*/
public class PushNumberCommand implements Command {
private final double number;

public PushNumberCommand(double number) {
this.number = number;
}

@Override
public void apply(Stack<Double> stack) throws ParsingException {
stack.push(number);
}
}
Loading