中缀表达式计算器球拍
Infix expression calculator racket
所以我得到了这个代码:
#lang pl
#| BNF for the AE language:
<AE> ::= <num>
| { + <AE> <AE> }
| { - <AE> <AE> }
| { * <AE> <AE> }
| { / <AE> <AE> }
|#
;; AE abstract syntax trees
(define-type AE
[Num Number]
[Add AE AE]
[Sub AE AE]
[Mul AE AE]
[Div AE AE])
(: parse-sexpr : Sexpr -> AE)
;; to convert s-expressions into AEs
(define (parse-sexpr sexpr)
(match sexpr
[(number: n) (Num n)]
[(list '+ lhs rhs)
(Add (parse-sexpr lhs) (parse-sexpr rhs))]
[(list '- lhs rhs)
(Sub (parse-sexpr lhs) (parse-sexpr rhs))]
[(list '* lhs rhs)
(Mul (parse-sexpr lhs) (parse-sexpr rhs))]
[(list '/ lhs rhs)
(Div (parse-sexpr lhs) (parse-sexpr rhs))]
[else
(error 'parse-sexpr "bad syntax in ~s" sexpr)]))
(: parse : String -> AE)
;; parses a string containing an AE expression to an AE AST
(define (parse str)
(parse-sexpr (string->sexpr str)))
(: eval : AE -> Number)
;; consumes an AE and computes the corresponding number
(define (eval expr)
(cases expr
[(Num n) n]
[(Add l r) (+ (eval l) (eval r))]
[(Sub l r) (- (eval l) (eval r))]
[(Mul l r) (* (eval l) (eval r))]
[(Div l r) (/ (eval l) (eval r))]))
(: run : String -> Number)
;; evaluate an AE program contained in a string
(define (run str)
(eval (parse str)))
你可以测试 运行 和 run (+ 3 5)
一起你会得到 8.
我的任务是更改代码,这样我就可以做到 run (3 + 5)
所以我将自己构建树的 parse-sexpr 函数更改为:
(: parse-sexpr : Sexpr -> AE)
;; to convert s-expressions into AEs
(define (parse-sexpr sexpr)
(match sexpr
[(number: n) (Num n)]
[(list lhs '+ rhs)
(Add (parse-sexpr lhs) (parse-sexpr rhs))]
[(list lhs '- rhs)
(Sub (parse-sexpr lhs) (parse-sexpr rhs))]
[(list lhs '* rhs)
(Mul (parse-sexpr lhs) (parse-sexpr rhs))]
[(list lhs '/ rhs)
(Div (parse-sexpr lhs) (parse-sexpr rhs))]
[else
(error 'parse-sexpr "bad syntax in ~s" sexpr)]))
我仍然可以编译代码,但是如果我这样做 run (+ 5 3)
我会得到 8 如果我尝试 run (5 + 3)
我得到:
Type Checker: Cannot apply expression of type Positive-Byte, since
it is not a function type in: (5 + 3)
为什么会这样?
你是不是偶然写的
(run (+ 5 3))
而不是
(run '(+ 5 3))
?
如果你写(run (+ 5 3))
那么Racket会先计算(+ 5 3)
,然后调用(run 8)
。如果你写 (run (5 + 3))
然后 Racket 将尝试评估 (5 + 3)
并且会给出你看到的错误:数字 5
不是函数类型,所以它不能像 (5 ...)
.
这是关于什么是打字球拍中的表达式与什么是您的语言中的表达式的问题。在您的语言中,(5 + 3)
是一个表达式,但在打字的球拍中,它是一个类型错误。因此,您需要在类型球拍中将 (5 + 3)
表示为 data。
正如@soegaard 指出的那样,一种常见的方法是在其前面放置一个 quote
,如下所示:'(5 + 3)
。虽然我讨厌那样写。 真正是(list 5 '+ 3)
。所以你可以把它传递给你的新 parse-sexpr
函数来得到
> (parse-sexpr (list 5 '+ 3))
- : AE
(Add (Num 5) (Num 3))
然后你可以将该值传递给你的eval
函数来得到
> (eval (Add (Num 5) (Num 3)))
- : Number
8
组合在一起:
> (eval (parse-sexpr (list 5 '+ 3)))
- : Number
8
但是您的 run
函数接受一个字符串,将其传递给 string->sexpr
,然后将其传递给 parse-sexpr
,然后传递给您的 eval
函数。所以你可能一直想做的是:
> (eval (parse-sexpr (string->sexpr "{5 + 3}")))
- : Number
8
> (run "{5 + 3}")
- : Number
8
假设 string->sexpr
接受带有花括号的表达式。您正在做的是 (run (5 + 3))
,它将 (5 + 3)
视为类型化的球拍表达式。您想要的是 (run "{5 + 3}")
,它将 (5 + 3)
视为您的语言中的表达式,在类型化的球拍中表示为数据。
所以我得到了这个代码:
#lang pl
#| BNF for the AE language:
<AE> ::= <num>
| { + <AE> <AE> }
| { - <AE> <AE> }
| { * <AE> <AE> }
| { / <AE> <AE> }
|#
;; AE abstract syntax trees
(define-type AE
[Num Number]
[Add AE AE]
[Sub AE AE]
[Mul AE AE]
[Div AE AE])
(: parse-sexpr : Sexpr -> AE)
;; to convert s-expressions into AEs
(define (parse-sexpr sexpr)
(match sexpr
[(number: n) (Num n)]
[(list '+ lhs rhs)
(Add (parse-sexpr lhs) (parse-sexpr rhs))]
[(list '- lhs rhs)
(Sub (parse-sexpr lhs) (parse-sexpr rhs))]
[(list '* lhs rhs)
(Mul (parse-sexpr lhs) (parse-sexpr rhs))]
[(list '/ lhs rhs)
(Div (parse-sexpr lhs) (parse-sexpr rhs))]
[else
(error 'parse-sexpr "bad syntax in ~s" sexpr)]))
(: parse : String -> AE)
;; parses a string containing an AE expression to an AE AST
(define (parse str)
(parse-sexpr (string->sexpr str)))
(: eval : AE -> Number)
;; consumes an AE and computes the corresponding number
(define (eval expr)
(cases expr
[(Num n) n]
[(Add l r) (+ (eval l) (eval r))]
[(Sub l r) (- (eval l) (eval r))]
[(Mul l r) (* (eval l) (eval r))]
[(Div l r) (/ (eval l) (eval r))]))
(: run : String -> Number)
;; evaluate an AE program contained in a string
(define (run str)
(eval (parse str)))
你可以测试 运行 和 run (+ 3 5)
一起你会得到 8.
我的任务是更改代码,这样我就可以做到 run (3 + 5)
所以我将自己构建树的 parse-sexpr 函数更改为:
(: parse-sexpr : Sexpr -> AE)
;; to convert s-expressions into AEs
(define (parse-sexpr sexpr)
(match sexpr
[(number: n) (Num n)]
[(list lhs '+ rhs)
(Add (parse-sexpr lhs) (parse-sexpr rhs))]
[(list lhs '- rhs)
(Sub (parse-sexpr lhs) (parse-sexpr rhs))]
[(list lhs '* rhs)
(Mul (parse-sexpr lhs) (parse-sexpr rhs))]
[(list lhs '/ rhs)
(Div (parse-sexpr lhs) (parse-sexpr rhs))]
[else
(error 'parse-sexpr "bad syntax in ~s" sexpr)]))
我仍然可以编译代码,但是如果我这样做 run (+ 5 3)
我会得到 8 如果我尝试 run (5 + 3)
我得到:
Type Checker: Cannot apply expression of type Positive-Byte, since it is not a function type in: (5 + 3)
为什么会这样?
你是不是偶然写的
(run (+ 5 3))
而不是
(run '(+ 5 3))
?
如果你写(run (+ 5 3))
那么Racket会先计算(+ 5 3)
,然后调用(run 8)
。如果你写 (run (5 + 3))
然后 Racket 将尝试评估 (5 + 3)
并且会给出你看到的错误:数字 5
不是函数类型,所以它不能像 (5 ...)
.
这是关于什么是打字球拍中的表达式与什么是您的语言中的表达式的问题。在您的语言中,(5 + 3)
是一个表达式,但在打字的球拍中,它是一个类型错误。因此,您需要在类型球拍中将 (5 + 3)
表示为 data。
正如@soegaard 指出的那样,一种常见的方法是在其前面放置一个 quote
,如下所示:'(5 + 3)
。虽然我讨厌那样写。 真正是(list 5 '+ 3)
。所以你可以把它传递给你的新 parse-sexpr
函数来得到
> (parse-sexpr (list 5 '+ 3))
- : AE
(Add (Num 5) (Num 3))
然后你可以将该值传递给你的eval
函数来得到
> (eval (Add (Num 5) (Num 3)))
- : Number
8
组合在一起:
> (eval (parse-sexpr (list 5 '+ 3)))
- : Number
8
但是您的 run
函数接受一个字符串,将其传递给 string->sexpr
,然后将其传递给 parse-sexpr
,然后传递给您的 eval
函数。所以你可能一直想做的是:
> (eval (parse-sexpr (string->sexpr "{5 + 3}")))
- : Number
8
> (run "{5 + 3}")
- : Number
8
假设 string->sexpr
接受带有花括号的表达式。您正在做的是 (run (5 + 3))
,它将 (5 + 3)
视为类型化的球拍表达式。您想要的是 (run "{5 + 3}")
,它将 (5 + 3)
视为您的语言中的表达式,在类型化的球拍中表示为数据。