Files
exercise04/index.typ
2025-11-05 16:41:24 +01:00

194 lines
4.4 KiB
Typst

#import "@preview/codly:1.3.0": *
#import "@preview/codly-languages:0.1.1": *
#import "@preview/catppuccin:1.0.1": catppuccin, flavors
#show: codly-init.with()
#show: catppuccin.with(flavors.latte)
#codly(languages: codly-languages)
= Exercise 01
#let question(body) = block(
fill: luma(255),
inset: 8pt,
radius: 4pt
)[
#body
]
== 01 Eigentschaften einer Gramatik
#question[
Besitzen die folgenden Grammatiken die LL(1)-Eigenschaft?
Begründen Sie Ihre Antwort in textueller Form (warum LL(1), warum nicht LL(1)). Sollte es mindestens eine
LL(1)-Verletzungen geben, geben Sie bitte alle an. Geben Sie zudem für jede Grammatik, welche die LL(1)-
Eigenschaft nicht besitzt, die theoretisch minimale Anzahl an Vorgriffssymbolen an, die für das Parsen der
jeweiligen Grammatik notwendig wäre.
]
=== Task a
#question[
```
Temperature = ["-"] ( Celsius | Kelvin ) .
Celsius = { number } "◦C" .
Kelvin = { number } "K" .
```
]
Conflicts:
- $"first"("Celsius") inter "first"("Kelvin") = { "number" } arrow.r.double "LL(1) conflict" $
- Both productions begin with the same token (number). This is a LL(1) conflict.
- It is not even LL(k) because there can be infinite (number) token before the distiction between Celsius and Kelvin happens.
=== Task b
#question[
```
Locals = "class" ident "{" { VarDecl | FuncDecl } "}" .
VarDecl = "int" ident { "," ident } ";" .
FuncDecl = "fn" "int" ident "(" ")" ";" .
```
]
$
"first"("FunDecl") inter "first"("VarDecl") = {"\"int\""} inter {"\"fn\""} = emptyset
$
$
("follow"("VarDecl") union "follow"("FuncDecl")) inter ("first"("FunDecl") union "first"("VarDecl")) \
= {"\"int\"", "\"fn\""} inter { "\"}\"" } = emptyset
$
- No LL(1) conflict
- No left recursion
- Grammer is LL(1)
=== Task c
#question[
```
Var = ident ":" Type .
Type = ( Primitive | FuncType ) .
Primitive = "i32" | "f64" .
FuncType = Type "->" Primitive .
```
]
- There is left recurion. Which means that the grammar is not LL(1). Consider the following snippet. The first element of `FuncType` evaluates to `Type`, which then can evaluate to `FuncType` => left recursion
```
FuncType = Type "->" Primitive .
Type = ( Primitive | FuncType ) .
```
- `First(Type)` can also not be computed because of the left recursion. So checking the intersection of `First(Type)` and `First(FuncType)` is not possible.
- Allthogh it is not LL(1) it is LL(2).
== 02 Beseitigung von LL(1)-Konflikten mittels Faktorisierung
Beseitigen Sie in folgenden Grammatiken die enthaltenen LL(1)-Konflikte mittels Einsetzen und Faktorisie-
rung. Geben Sie dazu eine umgeformte, ggf. vereinfachte EBNF Grammatik an.
=== Task a
#question[
```
StructDecl = ident "=" "{" { Value | NullableValue } "}" .
Value = ident ":" Type .
NullableValue = ident ":" "?" Type .
Type = "i32" | "i64" | "string" .
```
]
```
StructDecl = ident "=" "{" { NullableValue } "}" .
NullableValue = ident ":" ["?"] Type .
Type = "i32" | "i64" | "string" .
```
=== Task b
#question[
```
Args = FixArgs ";" VarArgs .
FixArgs = ident ":" Type { ";" ident ":" Type } .
VarArgs = "..." ident .
Type = "i32" | "string" .
```
]
```
Args = FixArgs VarArgs .
FixArgs = ident ":" Type ";" { ident ":" Type ";" } .
VarArgs = "..." ident .
Type = "i32" | "string" .
```
== 03 Beseitigung von Linksrekursion
#question[
Beseitigen Sie in folgender Grammatik die enthaltenen LL(1)-Konflikte. Geben Sie dazu eine umgeformte
EBNF Grammatik ohne Rekursion an. Beseitigen Sie mögliche Linksrekursionen durch Umformung in eine
Iteration (nicht durch Umformung in Rechtsrekursion).
```
Fields = Type Assigns .
Assigns = ident "=" Expr .
Expr = ident | number | Expr ( "==" | "!=" ) ( ident | number ) .
Type = ident | Type "->" ident .
```
]
First lets look at the Type Production:
```
Type = ident | Type "->" ident .
```
This can be rewritten as:
```
Type = ident { "->" ident } .
```
Seconnd we need to address the Expr Production:
```
Expr = ident | number | Expr ( "==" | "!=" ) ( ident | number ) .
```
This can be rewritten as:
```
Expr = ( ident | number ) { ( "==" | "!=" ) ( ident | number ) } .
```
The resulting grammer would be this:
```
Fields = Type Assigns .
Assigns = ident "=" Expr .
Expr = ( ident | number ) { ( "==" | "!=" ) ( ident | number ) } .
Type = ident { "->" ident } .
```
== 04 LL(4) Grammatik
#question[
Geben Sie eine einfache Grammatik mit mindestens 3 Produktionen an, welche die LL(4)-Eigenschaft, jedoch
nicht die LL(3)-Eigenschaft besitzt.
]
```
A = B | C .
B = "one" "two" "three" "B" .
C = "one" "two" "three" "C" .
```