diff --git a/04-typed-racket/main.rkt b/04-typed-racket/main.rkt index e88de19..9e9ce8d 100644 --- a/04-typed-racket/main.rkt +++ b/04-typed-racket/main.rkt @@ -12,10 +12,9 @@ [(and (even? a) (even? b)) (* 2 (gcd2 (floor (/ a 2)) (floor (/ b 2))))] [(even? b) (gcd2 a (floor (/ b 2)))] [(even? a) (gcd2 (floor (/ a 2)) b)] - [else - (if (<= a b) - (gcd2 a (- b a)) - (gcd2 b (- a b)))])) + [else (if (<= a b) + (gcd2 a (- b a)) + (gcd2 b (- a b)))])) (test (gcd2 0 0) => 0) (test (gcd2 288 64) => 32) @@ -102,4 +101,4 @@ (goodies/help good? l 0 '())) (test (goodies even? '(1 2 3 4 5)) => '(1 3)) -(test (goodies even? '()) => '()) \ No newline at end of file +(test (goodies even? '()) => '()) diff --git a/05-parsing/main.rkt b/05-parsing/main.rkt index 95ee9e2..aec641b 100644 --- a/05-parsing/main.rkt +++ b/05-parsing/main.rkt @@ -1,5 +1,32 @@ #lang pl +#| + +"{{{2 + 5}} * {5 * {{3 + 6}}}}" +The parenthesis ^here & ^here are necessary because otherwise it would be an AE, not a Prod as R3 requires. It requires this to maintain order of operations. + +"{{{2 + 5}} * {5 * {{3 * 6}}}}" +The parenthesis are no longer needed, as {3 * 6} is itself a prod satisfying R3. + +If you have a grammar language with easy precedence, it's nice. Otherwise, it's cursed. + +In Yacc: +%left ADD SUB +%left MUL DIV +%precedence NEG + +exp: + ... + | NUM {...} + | GROUPSTART exp GROUPEND { ... } + | SUB exp {...} + | exp SUM exp {...} + | exp SUB exp {...} + | exp MUL exp {...} + | exp DIV exp {...} + +|# + (define-type AE [R1 Prod AE] [R2 Prod]) @@ -12,30 +39,46 @@ [R5 Number] [R6 AE]) +#| + ::= + (1) + | (2) + ::= * (3) + | (4) + ::= (5) + | { } (6) +|# + ; Symbols: ; 'sum ; 'mul ; 'groups ; 'groupe -; parse-ae: s: Sexpr → AE -(: parse-ae : (Sexpr -> AE)) -; Parse a Sexpr. -(define (parse-ae s) - ; parseae: s: Sexpr, a: Sexpr → AE - (: parseae : (Sexpr Sexpr -> AE)) - ; Parse a Sexpr and while accumulating in a. - (define (parseae s a) - (match s - [(list prod ae) (parseae/group (rest s) '())] - [(cons (number: n) r) (R2 (R4 (R5 n)))])) +(: parseae : (Sexpr -> AE)) +(define (parseae s) + (match s + [(list prod '+ ae) (R1 (parseprod prod) (parseae ae))] + [prod (R2 (parseprod prod))])) - (parseae s '())) +(: parseprod : (Sexpr -> Prod)) +(define (parseprod s) + (match s + [(list atom '* prod) (R3 (parseatom atom) (parseprod prod))] + [ atom (R4 (parseatom atom))])) +(: parseatom : (Sexpr -> Atom)) +(define (parseatom s) + (match s + [ (number: n) (R5 n)] + [(list ae) (R6 (parseae ae))])) -(test (parse-ae '(3)) => (R2 (R4 (R5 3)))) -(test (parse-ae '(groups 3 groupe)) => (R2 (R4 (R6 (R2 (R4 (R5 3))))))) -(test (parse-ae '(1 plus 1)) => (R1 (R4 (R5 1)) (R2 (R4 (R5 1))))) +(: parse : (String -> AE)) +(define (parse s) (parseae (string->sexpr s))) + +(test (parse "5") => (R2 (R4 (R5 5)))) +(test (parse "{2 + 5}") => (R1 (R4 (R5 2)) (R2 (R4 (R5 5))))) +(test (parse "{{{2 + 5}} * {5 * {{3 + 6}}}}") => (R2 (R3 (R6 (R1 (R4 (R5 2)) (R2 (R4 (R5 5))))) (R3 (R5 5) (R4 (R6 (R1 (R4 (R5 3)) (R2 (R4 (R5 6))))))))) + ) ; parse-ae/h: s: Sexpr, ae: AE → AE @@ -49,6 +92,8 @@ ::= (5) | { } (6) +These are not wrapped in the few rules at the top level to convert them to AEs + "5" (5) 5