Skip to content

Commit c39f2b2

Browse files
committed
week5 praksi lahendused
1 parent 98faa7e commit c39f2b2

3 files changed

Lines changed: 172 additions & 0 deletions

File tree

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package week5.grammar;
2+
3+
import week4.regex.RegexParser;
4+
import week4.regex.ast.*;
5+
6+
public class RegexGrammar {
7+
8+
// Konstandid ilutrüki jaoks
9+
private static final char EPS = 'ε';
10+
private static final String ARROW = " → ";
11+
12+
public static void printGrammar(RegexNode node) {
13+
new RegexGrammar().printGrammarNode(node, 'S');
14+
}
15+
16+
private char nextNt = 'A';
17+
// Genereeri järgmine mitte-terminal (eeldades, et neid liiga palju ei ole).
18+
private char getNextNt() {
19+
if (nextNt == 'S') nextNt++; // Jätame S vahele, et seda saaks kasutada algsümbolina.
20+
return nextNt++;
21+
}
22+
23+
/**
24+
* @param nt Praegu defineeritav mitte-terminal
25+
*/
26+
private void printGrammarNode(RegexNode regex, char nt) {
27+
switch (regex) {
28+
case Letter(char symbol) -> System.out.println(nt + ARROW + symbol);
29+
case Epsilon _ -> System.out.println(nt + ARROW + EPS);
30+
case Repetition(RegexNode child) -> {
31+
char childNt = getNextNt();
32+
System.out.println(nt + ARROW + childNt + nt);
33+
System.out.println(nt + ARROW + EPS);
34+
printGrammarNode(child, childNt);
35+
}
36+
case Concatenation(RegexNode left, RegexNode right) -> {
37+
char leftNt = getNextNt();
38+
char rightNt = getNextNt();
39+
System.out.println(nt + ARROW + leftNt + rightNt);
40+
printGrammarNode(left, leftNt);
41+
printGrammarNode(right, rightNt);
42+
}
43+
case Alternation(RegexNode left, RegexNode right) -> {
44+
char leftNt = getNextNt();
45+
char rightNt = getNextNt();
46+
System.out.println(nt + ARROW + leftNt);
47+
System.out.println(nt + ARROW + rightNt);
48+
printGrammarNode(left, leftNt);
49+
printGrammarNode(right, rightNt);
50+
}
51+
}
52+
}
53+
54+
static void main() {
55+
printGrammar(RegexParser.parse("(a|bc)*"));
56+
}
57+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package week5.kalalexer;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
import static week5.kalalexer.KalaToken.Type.*;
7+
8+
public class KalaLexer {
9+
private static final char TERMINATOR = '\0';
10+
private final String input;
11+
private int pos;
12+
13+
public KalaLexer(String input) {
14+
this.input = input + TERMINATOR;
15+
pos = 0;
16+
}
17+
18+
public List<KalaToken> readAllTokens() {
19+
List<KalaToken> tokens = new ArrayList<>();
20+
while (peek() != TERMINATOR) {
21+
switch (peek()) {
22+
case '(':
23+
tokens.add(new KalaToken(LPAREN));
24+
pos++;
25+
break;
26+
case ')':
27+
tokens.add(new KalaToken(RPAREN));
28+
pos++;
29+
break;
30+
case ',':
31+
tokens.add(new KalaToken(COMMA));
32+
pos++;
33+
break;
34+
default:
35+
if (Character.isLetter(peek())) {
36+
KalaToken tok = readIdentOrNull();
37+
tokens.add(tok);
38+
} else pos++;
39+
}
40+
}
41+
tokens.add(new KalaToken(EOF));
42+
return tokens;
43+
}
44+
45+
private KalaToken readIdentOrNull() {
46+
StringBuilder sb = new StringBuilder();
47+
while (Character.isLetter(peek())) {
48+
sb.append(peek());
49+
pos++;
50+
}
51+
if (sb.toString().equals("null")) {
52+
return new KalaToken(NULL);
53+
} else
54+
return new KalaToken(IDENT, sb.toString());
55+
}
56+
57+
private char peek() {
58+
return input.charAt(pos);
59+
}
60+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package week5.kalalexer;
2+
3+
import java.io.IOException;
4+
import java.nio.file.Files;
5+
import java.nio.file.Paths;
6+
import java.util.Arrays;
7+
8+
public class Unescaper {
9+
10+
/**
11+
* Töötleb sisendsõne selliselt, et escape'itud reavahetused on asendatud päris reavahetustega.
12+
*/
13+
private static String unescape(String str) {
14+
StringBuilder output = new StringBuilder();
15+
boolean escape = false;
16+
for (char c : str.toCharArray()) {
17+
if (escape) {
18+
if (c == 'n') output.append('\n');
19+
else throw new IllegalArgumentException("Unknown escape literal");
20+
escape = false;
21+
}
22+
else if (c == '\\') escape = true;
23+
else output.append(c);
24+
}
25+
return output.toString();
26+
}
27+
28+
29+
/**
30+
* Testime, kas meetod teeb seda, mida vaja failis inputs/escaped.txt oleva kirjutisega.
31+
*/
32+
static void main() throws IOException {
33+
34+
// Esialgne sõne:
35+
String mystring = "foo\nbar\nbaz";
36+
System.out.print("Original: ");
37+
System.out.println(Arrays.toString(mystring.toCharArray()));
38+
System.out.println();
39+
40+
// sisend failist
41+
String input = Files.readString(Paths.get("inputs", "escaped.txt")).trim();
42+
System.out.print("Input: ");
43+
System.out.println(Arrays.toString(input.toCharArray()));
44+
System.out.println();
45+
46+
// funktsiooni väljund
47+
String unescaped = unescape(input.substring(1, input.length() - 1));
48+
System.out.print("Unescaped: ");
49+
System.out.println(Arrays.toString(unescaped.toCharArray()));
50+
System.out.println();
51+
52+
// funktsiooni väljund peaks olema see, mis oodatud
53+
System.out.println(!unescaped.equals(mystring) ? "Ei tööta!" : "Suurepärane töö!");
54+
}
55+
}

0 commit comments

Comments
 (0)