fixed lab6 + report

This commit is contained in:
2024-04-22 19:24:11 +03:00
parent eb75cb0a3f
commit b6ae645808
10 changed files with 266 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
package ast_parser;
class BinaryOperatorExpr extends Expr {
Expr left;
Expr right;
char operator;
BinaryOperatorExpr(Expr left, Expr right, char operator) {
this.left = left;
this.right = right;
this.operator = operator;
}
@Override
double evaluate() {
return switch (operator) {
case '+' -> left.evaluate() + right.evaluate();
case '-' -> left.evaluate() - right.evaluate();
case '*' -> left.evaluate() * right.evaluate();
case '/' -> left.evaluate() / right.evaluate();
default -> throw new RuntimeException("Unsupported operator: " + operator);
};
}
}

5
src/ast_parser/Expr.java Normal file
View File

@@ -0,0 +1,5 @@
package ast_parser;
abstract class Expr {
abstract double evaluate();
}

View File

@@ -0,0 +1,50 @@
package ast_parser;
import java.util.List;
class FunctionExpr extends Expr {
String function;
List<Expr> arguments;
FunctionExpr(String function, List<Expr> arguments) {
this.function = function;
this.arguments = arguments;
}
@Override
double evaluate() {
return switch (function) {
case "sqrt" -> {
if (arguments.size() != 1) {
throw new RuntimeException("sqrt expects exactly one argument");
}
yield Math.sqrt(arguments.get(0).evaluate());
}
case "logtwo" -> {
if (arguments.size() != 1) {
throw new RuntimeException("log2 expects exactly one argument");
}
yield Math.log(arguments.get(0).evaluate()) / Math.log(2);
}
case "logten" -> {
if (arguments.size() != 1) {
throw new RuntimeException("log10 expects exactly one argument");
}
yield Math.log10(arguments.get(0).evaluate());
}
case "loge" -> {
if (arguments.size() != 1) {
throw new RuntimeException("loge expects exactly one argument");
}
yield Math.log(arguments.get(0).evaluate());
}
case "powtwo" -> {
if (arguments.size() != 1) {
throw new RuntimeException("pow2 expects exactly one argument");
}
yield Math.pow(2, arguments.get(0).evaluate());
}
default -> throw new RuntimeException("Unsupported function or wrong number of arguments: " + function);
};
}
}

51
src/ast_parser/Lexer.java Normal file
View File

@@ -0,0 +1,51 @@
package ast_parser;
import java.util.ArrayList;
import java.util.List;
public class Lexer {
public static List<Token> tokenize(String input) {
List<Token> tokens = new ArrayList<>();
input = input.replaceAll("\\s", "");
int i = 0;
while (i < input.length()) {
char ch = input.charAt(i);
if (Character.isDigit(ch)) {
StringBuilder sb = new StringBuilder();
while (i < input.length() && (Character.isDigit(input.charAt(i)) || input.charAt(i) == '.')) {
sb.append(input.charAt(i));
i++;
}
tokens.add(new Token(TokenType.NUMBER, sb.toString()));
} else if (Character.isLetter(ch)) {
StringBuilder sb = new StringBuilder();
while (i < input.length() && Character.isLetter(input.charAt(i))) {
sb.append(input.charAt(i));
i++;
}
tokens.add(new Token(TokenType.FUNCTION, sb.toString()));
} else {
switch (ch) {
case '(':
tokens.add(new Token(TokenType.LPAREN, "("));
i++;
break;
case ')':
tokens.add(new Token(TokenType.RPAREN, ")"));
i++;
break;
case ',':
tokens.add(new Token(TokenType.COMMA, ","));
i++;
break;
default:
tokens.add(new Token(TokenType.OPERATOR, String.valueOf(ch)));
i++;
break;
}
}
}
tokens.add(new Token(TokenType.EOF, ""));
return tokens;
}
}

View File

@@ -0,0 +1,17 @@
package ast_parser;
import java.util.List;
public class MainParser {
public static void main(String[] args) {
String input = "(3 + 5) * sqrt(16) + powtwo(5)";
List<Token> tokens = Lexer.tokenize(input);
System.out.println("Tokens:");
tokens.forEach(System.out::println);
Parser parser = new Parser(tokens);
Expr expression = parser.parse();
double result = expression.evaluate();
System.out.println("Result: " + result);
}
}

View File

@@ -0,0 +1,14 @@
package ast_parser;
class NumberExpr extends Expr {
double value;
NumberExpr(double value) {
this.value = value;
}
@Override
double evaluate() {
return value;
}
}

View File

@@ -0,0 +1,78 @@
package ast_parser;
import java.util.ArrayList;
import java.util.List;
public class Parser {
private final List<Token> tokens;
private int current = 0;
public Parser(List<Token> tokens) {
this.tokens = tokens;
}
public Expr parse() {
return expression();
}
private Expr expression() {
Expr expr = term();
while (match(TokenType.OPERATOR)) {
char operator = tokens.get(current - 1).value.charAt(0);
Expr right = term();
expr = new BinaryOperatorExpr(expr, right, operator);
}
return expr;
}
private Expr term() {
if (match(TokenType.NUMBER)) {
return new NumberExpr(Double.parseDouble(previous().value));
} else if (match(TokenType.LPAREN)) {
Expr expr = expression();
consume(TokenType.RPAREN, "Expect ')' after expression.");
return expr;
} else if (match(TokenType.FUNCTION)) {
String functionName = previous().value;
consume(TokenType.LPAREN, "Expect '(' after function name.");
List<Expr> args = new ArrayList<>();
if (!check(TokenType.RPAREN)) {
do {
args.add(expression());
} while (match(TokenType.COMMA));
}
consume(TokenType.RPAREN, "Expect ')' after arguments.");
return new FunctionExpr(functionName, args);
}
throw new RuntimeException("Unexpected token.");
}
private boolean match(TokenType type) {
if (check(type)) {
current++;
return true;
}
return false;
}
private boolean check(TokenType type) {
if (isAtEnd()) return false;
return tokens.get(current).type == type;
}
private Token previous() {
return tokens.get(current - 1);
}
private void consume(TokenType type, String message) {
if (check(type)) {
current++;
return;
}
throw new RuntimeException(message);
}
private boolean isAtEnd() {
return current >= tokens.size() || tokens.get(current).type == TokenType.EOF;
}
}

16
src/ast_parser/Token.java Normal file
View File

@@ -0,0 +1,16 @@
package ast_parser;
public class Token {
public TokenType type;
public String value;
public Token(TokenType type, String value) {
this.type = type;
this.value = value;
}
@Override
public String toString() {
return type + " : " + value;
}
}

View File

@@ -0,0 +1,11 @@
package ast_parser;
public enum TokenType {
NUMBER,
OPERATOR,
LPAREN,
RPAREN,
FUNCTION,
COMMA,
EOF
}

BIN
src/reports/lab_five.pdf Normal file

Binary file not shown.