finished exercise
This commit is contained in:
184
index.typ
Normal file
184
index.typ
Normal file
@@ -0,0 +1,184 @@
|
||||
#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.
|
||||
- The amount of lookahead symbols does not matter in this case. The grammar is not LL(k) for any k.
|
||||
|
||||
== 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 ) } .
|
||||
```
|
||||
|
||||
|
||||
== 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"
|
||||
```
|
||||
Reference in New Issue
Block a user