Hi All,

The syntax-parse form can often generate sensible errors based on the
progress made
during the attempt to match a pattern against a syntax-object. Given
multiple choices
the choice where the "maximum" progress was made is used to generate the
error message.

Is there a way to tell syntax-parse, that a given choice is to be used as
the source
of the error, if the match fails?

A concrete example: In the toy language below a top-level form can be a
definition
or an expression. The malformed definition (define (foo 3) x) is not a legal
definition -- it is however clear that the user intended to write a
definition,
since the form begins with (define ...). During matching syntax-parse
makes more progress under the assumption that the definition is a sequence
expression, so the error message becomes: begin expected.

How can I stop the matching prematurely when the (define ...) is seen?

/Jens Axel

#lang racket
;;;
;;; URLANG
;;;

; In the grammar below x stands for a non-keyword identifier

; <program>        ::= <top-level-form> ...
; <top-level-form> ::= <definition> | <expr>

; <definition>     ::= (define (x x ...) <body>)
; <body>           ::= <expr>

; <expr>           ::= <datum> | <reference> | <application> | <sequence>
; <reference>      ::= x
; <application>    ::= (x0 x ...)
; <sequence>       ::= (begin <expr> ...)

; <keyword>        ::= define | begin

; <datum>          ::= <fixnum>

; <identifier>     an identifier that is not a keyword
; <fixnum>         an integer between -2^53 and 2^53

(require syntax/parse)

(define min-fixnum (- (expt 2 53)))
(define max-fixnum    (expt 2 53))

(define (Fixnum? r)
  (and (number? r) (integer? r)
       (<= min-fixnum r max-fixnum)))

(define-syntax-class Fixnum
  #:opaque
  (pattern d
           #:fail-unless (Fixnum? (syntax-e #'d)) #f))

(define-syntax-class Datum
  (pattern (~or d:Fixnum)))

(define-syntax-class Keyword
  #:literals (begin define)
  (pattern (~or begin define)))

(define-syntax-class Id
  (pattern (~and x:id
                 (~not y:Keyword))))

(define-syntax-class Reference
  (pattern x:Id))

(define-syntax-class Application
  #:literals (define)
  (pattern (e:Expr ...)))

(define-syntax-class Sequence
  #:literals (begin)
  (pattern (begin e0:Expr e:Expr ...)))

(define-syntax-class Definition
  #:literals (define)
  (pattern (define (name:Id a:Id ...) body:Body)))


(define-syntax-class Body
  (pattern b:Expr))

(define-syntax-class Expr
  (pattern (~or e:Datum
                e:Application
                e:Reference
                e:Sequence)))

(define-syntax-class TopLevelForm
  (pattern (~or t:Definition
                t:Expr)))

(define-syntax-class Program
  (pattern (p:TopLevelForm ...)))

;;; The following expressions show some legal
;;; constructs that are matched correctly.

(syntax-parse #'3
  [d:Datum 'datum])

(syntax-parse #'3
  [e:Expr 'expr])

(syntax-parse #'(define (a x) x)
  [t:TopLevelForm 'toplevelform])

(syntax-parse #'((define (foo x y) (+ x 1)) (foo 3))
  [p:Program 'program])

;;; The malformed definition (define (a 4 x) x) is
;;; correctly rejected as a toplevel form, but the
;;; automatically generated error is not as intended.

(syntax-parse #'(define (a 4 x) x)
  [t:TopLevelForm 'toplevelform])

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to