194 lines
4.4 KiB
Typst
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" .
|
|
```
|