Проблема проверки типов при написании парсера в ракетке - PullRequest
0 голосов
/ 04 мая 2019

У меня есть язык PLANG, который поддерживает оценку полинома по последовательности точек (чисел).язык допускает выражения вида {{???? ?? ??… ??} {?? ??… ??}}, где все ?? и все ?? являются действительными выражениями AE (и оба ? ≥ 1 и ℓ ≥ 1).

Я пытался написать синтаксический анализ для этого языка, вот что у меня есть:

(define-type PLANG
  [Poly (Listof AE) (Listof AE)])
 (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 -> PLANG)
 ;; parses a string containing a PLANG expression to a PLANG AST

 (define (parse str)
 (let ([code (string->sexpr str)])
 (parse-sexpr (code) )))



(test (parse "{{poly 1 2 3} {1 2 3}}")
 => (Poly (list (Num 1) (Num 2) (Num 3))
 (list (Num 1) (Num 2) (Num 3))))
(test (parse "{{poly } {1 2} }") 
 =error> "parse: at least one coefficient is
 required in ((poly) (1 2))")
(test (parse "{{poly 1 2} {} }")
 =error> "parse: at least one point is
 required in ((poly 1 2) ())")

, когда я пытаюсь заставить его работать, я получаю ошибки:

Type Checker: Cannot apply expression of type (U (Listof Sexpr) Boolean Real String Symbol), since it is not a function type in: (code)
. Type Checker: type mismatch
  expected: Poly
  given: AE in: (parse-sexpr (code))
. Type Checker: Summary: 2 errors encountered in:
  (code)
  (parse-sexpr (code))
> 

Любая помощь будет оценена ..

1 Ответ

2 голосов
/ 04 мая 2019

Первая проблема вызвана лишней парой скобок. Имейте в виду, что в Racket, Typed Racket и #lang pl круглые скобки обычно означают применение функции следующим образом:

(function argument ...)

Поэтому, когда вы пишете (code), он пытается интерпретировать code как функцию, вызывая ее с нулевыми аргументами.

Эту проблему можно исправить, заменив (code) на code в теле функции parse.

(define (parse str)
  (let ([code (string->sexpr str)])
    (parse-sexpr code)))

Вторая проблема возникает из-за того, что вы указали, что функция parse должна возвращать PLANG, но вместо этого она возвращает результат parse-sexpr, который возвращает AE.

Еще один способ выразить это в том, что вы реализовали разбор для AE с, но не для PLANG с.

...