所以我得到了这段代码:
#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:不能应用Positive-Byte类型的表达式,因为 它不是函数类型:(5 + 3)
为什么会发生这种情况?
答案 0 :(得分:1)
你有没有写过
(run (+ 5 3))
而不是
(run '(+ 5 3))
如果你写(run (+ 5 3))
,那么Racket将首先计算(+ 5 3)
,然后拨打(run 8)
。如果您编写(run (5 + 3))
,那么Racket将尝试评估(5 + 3)
,并且会出现您看到的错误:数字5
不是函数类型,因此无法用作(5 ...)
1}}
答案 1 :(得分:1)
这是类型球拍中表达式的问题,而不是您的语言中的表达式。在您的语言中,(5 + 3)
是一个表达式,但在键入的球拍中,这是一个类型错误。因此,您需要在键入的球拍中将(5 + 3)
表示为数据。
正如@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)
视为您所用语言的表达式,在表格中表示为数据。