75 lines
1.6 KiB
Typst
75 lines
1.6 KiB
Typst
|
#import "@local/handout:0.1.0": *
|
||
|
#import "@preview/cetz:0.3.1"
|
||
|
|
||
|
#show: handout.with(
|
||
|
title: [Warm-Up: What's an AST?],
|
||
|
by: "Mark",
|
||
|
subtitle: "Based on a true story.",
|
||
|
)
|
||
|
|
||
|
#problem()
|
||
|
Say we have a valid string of simple arithmetic that contains \
|
||
|
no unary operators (like $3!$ or $-4$) and no parenthesis:
|
||
|
|
||
|
#v(2mm)
|
||
|
$
|
||
|
3 + 9 times 8 div 5 and 6
|
||
|
$
|
||
|
#v(2mm)
|
||
|
|
||
|
You may assume that all numbers and operators in this string consist of exactly one character. \
|
||
|
|
||
|
Devise an algorithm that turns such strings into a tree (as shown below), \
|
||
|
respecting the order of operations $[and, times, div, +, -]$.
|
||
|
|
||
|
#v(2mm)
|
||
|
|
||
|
#align(
|
||
|
center,
|
||
|
cetz.canvas({
|
||
|
import cetz.draw: *
|
||
|
|
||
|
// spell:off
|
||
|
content((0, 0), $+$, name: "r")
|
||
|
content((-0.5, -1), $3$, name: "a")
|
||
|
content((0.5, -1), $div$, name: "b")
|
||
|
content((-0.3, -2), $times$, name: "ba")
|
||
|
content((1.3, -2), $and$, name: "bb")
|
||
|
content((-0.8, -3), $9$, name: "baa")
|
||
|
content((0.2, -3), $8$, name: "bab")
|
||
|
content((0.8, -3), $5$, name: "bba")
|
||
|
content((1.8, -3), $6$, name: "bbb")
|
||
|
// spell:on
|
||
|
|
||
|
// Zero-sized arrows are a hack for offset.
|
||
|
set-style(
|
||
|
stroke: (thickness: 0.3mm),
|
||
|
mark: (
|
||
|
start: (
|
||
|
symbol: "|",
|
||
|
offset: 0.25,
|
||
|
width: 0mm,
|
||
|
length: 0mm,
|
||
|
),
|
||
|
end: (
|
||
|
symbol: "|",
|
||
|
offset: 0.25,
|
||
|
width: 0mm,
|
||
|
length: 0mm,
|
||
|
),
|
||
|
),
|
||
|
)
|
||
|
|
||
|
// spell:off
|
||
|
line("r", "a")
|
||
|
line("r", "b")
|
||
|
line("b", "ba")
|
||
|
line("b", "bb")
|
||
|
line("ba", "baa")
|
||
|
line("ba", "bab")
|
||
|
line("bb", "bba")
|
||
|
line("bb", "bbb")
|
||
|
// spell:on
|
||
|
}),
|
||
|
)
|