[racket] Syntax-parse and error messages

From: Ryan Culpepper (ryanc at ccs.neu.edu)
Date: Wed Oct 13 05:16:53 EDT 2010

On 10/13/2010 10:41 AM, Jens Axel Søgaard wrote:
> Hi All,
>
> I am experimenting with syntax-parse in order to generate precise
> error messages with a minimum of fuss. So far it looks very promising,
> but I have a few questions.
>
> Below I have systematically define syntax-classes for each
> non-terminal in the grammar of cas-cade-e expressions.
> I have used this grammar:
>
> ;;; SYNTAX
> ;;<cas-cad-e>    ::= (cas-cad-e<val-expr>  <case-clause>  ...+)
> ;;<case-clause>  ::= [(<datum>  ...)<then-expr>  ...+]
>
> Each syntax class is given a description, which is included in
> an error message, when some expression fails to parse (and
> it is expected to).
>
> To focus on the error messages I have removed the expansion.
> Below I have tried to test which error messages I got.
>
> For  (casc)   I get the correct error message, namely
>      casc: expected<cas-cad-expr>  of the form (cas-cad-e<value-expr>
> <case-clause>  ...+) after 1 term in: (casc)
>
> For     (casc #:foo)   I expected the error:
>              "casc: expected value-expr in: #:foo"
> but got  "casc: expected expr in: #:foo".
> How do I make syntax-parse give the precise error?

syntax-parse considers "expr" the more precise error in this case, since 
it occurs within the other syntax class (value-expr). I've considered 
adding a "role" annotation to pattern variables, orthogonal to syntax 
classes, that would let you express something like "expected expression 
for the clause value". But I haven't added it yet.

In the meantime, you can make value-expr opaque (#:opaque), and that 
should mask out the expr error.

> For   (casc 3 [(4) ])  where the<then-expr>  ...+ part is omitted
> I get the error message:
>     ; casc: repetition constraint violated in: (casc 3 ((4)))
> It is of course correct that the "at least one" repitition contraint
> is violated,
> but how do I get syntax-parse to tell me, that it is due to a missing
> <then-expr>  in  a<case-clause>?

The generic error message "repetition constraint violated" has been 
removed in recent versions of syntax-parse, BTW.

At the moment, the only way to customize the error message here is to use

   ((~between te:then-expr 1 +inf.0 #:name "result expression") ...)

or see the other options of ~between.

Ryan



> #lang racket
> (require
>   racket/stxparam
>   (for-syntax unstable/syntax ; for generate-temporary
>                       syntax/parse
>                       syntax/stx))
> ;;; SYNTAX
> ;;<cas-cad-e>    ::= (cas-cad-e<val-expr>  <case-clause>  ...+)
> ;;<case-clause>  ::= [(<datum>  ...)<then-expr>  ...+]
>
> (define-syntax-parameter break
>    (λ (stx) (raise-syntax-error 'break "The keywork break was used of
> context." stx)))
>
> (define-syntax (casc stx)
>    (define-syntax-class datum
>      #:attributes (d)
>      #:description "<datum>  part of the literal list in a<case-clause>"
>      (pattern d:expr))
>    (define-syntax-class then-expr
>      #:attributes (e)
>      #:description "an expression part to be part of a<case-clause>"
>      (pattern e:expr))
>    (define-syntax-class case-clause
>      #:attributes ((d 1) (te 1))
>      #:description "<case-clause>  of the form [(<datum>  ...)<then-expr>  ...+"
>      (pattern [(d:datum ...) te:then-expr ...+]))
>    (define-syntax-class value-expr
>      #:attributes (e)
>      #:description "value-expr"
>      (pattern e:expr))
>    (define-syntax-class cas-cad-expr
>      #:attributes (ve (c 1) last-c)
>      #:description "<cas-cad-expr>  of the form (cas-cad-e<value-expr>
> <case-clause>  ...+)"
>      (pattern (_ ve:value-expr c:case-clause ... last-c:case-clause)))
>    (syntax-parse stx
>      [usage:cas-cad-expr
>       #'42]))
>
> ;; Expressions that must signal an error
>
> (casc) ; correct error message
> ;(casc #:foo)  ; I expected the error:  "casc: expected value-expr
> ..." but got "expected expr ..."
> ;(casc 3 [(4) ])  ; casc: repetition constraint violated in: (casc 3 ((4)))
> ;(casc 3 [(4) 2 3] [3])    ; only 3 is red  shouldn't that be [3] ?
>
>
> ;; And a legal expression
> (casc 3
>        [(1) 'one]
>        [(3) 'three])
>
> --
> Jens Axel Søgaard
> _________________________________________________
>    For list-related administrative tasks:
>    http://lists.racket-lang.org/listinfo/users



Posted on the users mailing list.