Skip to content

Commit e56aae1

Browse files
committed
Trzecia wersja interpretatora
1 parent 4d46739 commit e56aae1

File tree

4 files changed

+128
-6
lines changed

4 files changed

+128
-6
lines changed

src/main/java/pl/koder95/interpreter/Interpreter.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,33 @@ public interface Interpreter<C extends Context, R> {
1212
* @return kontekst używany podczas interpretacji wyrażeń terminalnych
1313
*/
1414
C getContext();
15+
16+
/**
17+
* @return {@link Tokenizer tokenizer} używany przez {@link Parser parser} do budowy drzewa składni
18+
*/
19+
Tokenizer getTokenizer();
20+
/**
21+
* @return {@link Parser parser}, który pobiera tokeny, aby stworzyć drzewo składniowe
22+
*/
23+
Parser<C, R> getParser();
1524

1625
/**
17-
* Buduje drzewo abstrakcyjnej syntaktyki.
18-
* @param expression wyrażenie
19-
* @return wyrażenie terminalne najwyższego poziomu
26+
* @return fabryka {@link java.util.Scanner skanerów}, które standardowo pomagają w przetwarzaniu danych wejściowych
2027
*/
21-
TerminalExpression<C,R> buildAbstractSyntaxTree(String expression);
28+
ScannerFactory getScannerFactory();
2229

2330
/**
2431
* Dokonuje interpretacji danych wejściowych korzystając z {@link Context kontekstu}. Dane najpierw są tokenizowane
2532
* i zamieniane na {@link NonTerminalExpression wyrażenia nieterminalne}, aby zbudować z nich drzewo abstrakcyjnej
2633
* syntaktyki (AST).
2734
*
35+
* @param readable dane odczytywane przez tokenizer i zamieniane na postać terminalną
2836
* @return wynik interpretacji
2937
*/
30-
default R interpret(String expression) {
31-
TerminalExpression<C, R> ast = buildAbstractSyntaxTree(expression);
38+
default R interpret(Readable readable) {
39+
Tokenizer tokenizer = getTokenizer();
40+
tokenizer.useScanner(getScannerFactory().create(readable));
41+
TerminalExpression<C, R> ast = getParser().buildAbstractSyntaxTree(tokenizer.enqueue());
3242
return ast.interpret(getContext());
3343
}
3444
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package pl.koder95.interpreter;
2+
3+
import java.util.Queue;
4+
5+
/**
6+
* Interfejs dostarczający metodę, która buduje drzewo abstrakcyjnej syntaktyki.
7+
* @param <C> typ {@link Context kontekstu} dla {@link TerminalExpression wyrażenia terminalnego}
8+
* @param <R> typ obiektu zwracanego przez interpreter
9+
*/
10+
public interface Parser<C extends Context, R> {
11+
12+
/**
13+
* Buduje drzewo abstrakcyjnej syntaktyki.
14+
* @param tokens dane wejściowe poddane tokenizacji
15+
* @return wyrażenie terminalne najwyższego poziomu
16+
*/
17+
TerminalExpression<C, R> buildAbstractSyntaxTree(Queue<NonTerminalExpression<?>> tokens);
18+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package pl.koder95.interpreter;
2+
3+
import java.util.Scanner;
4+
5+
/**
6+
* Fabryka {@link Scanner skanerów}.
7+
* Implementacja pozwala na określenie dowolnych właściwości skanera przed jego użyciem,
8+
* takich jak {@link Scanner#delimiter() znak delimitera}. Domyślna implementacja tworzy
9+
* skaner z domyślnymi właściwościami.
10+
*/
11+
public interface ScannerFactory {
12+
13+
/**
14+
* Tworzy nową instancję skanera dostosowaną do konkretnych zastosowań.
15+
*
16+
* @param readable dane wejściowe możliwe do odczytania przez interfejs {@link Readable}
17+
* @return nowa instancja {@link Scanner skanera}
18+
*/
19+
default Scanner create(Readable readable) {
20+
return new Scanner(readable);
21+
}
22+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package pl.koder95.interpreter;
2+
3+
import java.util.Queue;
4+
import java.util.Scanner;
5+
import java.util.concurrent.LinkedBlockingQueue;
6+
7+
/**
8+
* Definiuje sposób podziału danych wejściowych na tokeny.
9+
* Standardowo korzysta ze {@link Scanner skanera}, aby dzielić i analizować ciąg odczytywanych wartości.
10+
* Nic nie stoi na przeszkodzie, aby użyć innego sposobu. Wystarczy oprócz implementacji metody {@link #next()}
11+
* nadpisać metodę {@link #hasNext()}.
12+
*/
13+
public abstract class Tokenizer {
14+
15+
private Scanner scanner;
16+
17+
/**
18+
* Tworzy nową instancję tokenizera ustawiając skaner na wartość {@code null}.
19+
* Dla poprawnego funkcjonowania należy wywołać metodę {@link #useScanner(Scanner)}.
20+
*/
21+
public Tokenizer() {
22+
this.scanner = null;
23+
}
24+
25+
/**
26+
* @param scanner skaner używany podczas procesu tokenizacji danych wejściowych
27+
*/
28+
public void useScanner(Scanner scanner) {
29+
this.scanner = scanner;
30+
}
31+
32+
/**
33+
* Metoda używana podczas procesu tworzenia tokenów w metodzie {@link #next()}.
34+
* @return zwraca aktualnie ustawiony skaner
35+
*/
36+
protected final Scanner getScanner() {
37+
return scanner;
38+
}
39+
40+
/**
41+
* Umieszcza w kolejce wszystkie możliwe do odczytania tokeny.
42+
* @param queue kolejka wyrażeń nieterminalnych (tokenów)
43+
* @return {@code queue}
44+
*/
45+
public final Queue<NonTerminalExpression<?>> enqueue(Queue<NonTerminalExpression<?>> queue) {
46+
while (hasNext()) queue.add(next());
47+
return queue;
48+
}
49+
50+
/**
51+
* Tworzy nową kolejkę wyrażeń nieterminalnych (tokenów) i umieszcza w niej odczytane tokeny z wejścia.
52+
* @return nowa instancja kolejki {@link NonTerminalExpression wyrażeń nieterminalnych (tokenów)}
53+
*/
54+
public Queue<NonTerminalExpression<?>> enqueue() {
55+
return enqueue(new LinkedBlockingQueue<>());
56+
}
57+
58+
/**
59+
* Sprawdza, czy istnieje możliwość pobrania następnego tokenu.
60+
* @return {@code true} – jeśli istnieje następny token, {@code false} w przeciwnym razie
61+
*/
62+
public boolean hasNext() {
63+
return scanner != null && scanner.hasNext();
64+
}
65+
66+
/**
67+
* Przetwarza dane wejściowe i zwraca je w postaci {@link NonTerminalExpression wyrażenia nieterminalnego},
68+
* czyli tokenu.
69+
* @return token typu {@link NonTerminalExpression}
70+
*/
71+
public abstract NonTerminalExpression<?> next();
72+
}

0 commit comments

Comments
 (0)