On 10/21/2016 05:50 PM, Dan Liebgold wrote:
Hi all -

In the process of putting together a somewhat complex application
using syntax-parse, I discovered that when I specified a repeated
pattern in a syntax-class (which was incorrect) AND I had a certain
usage of the syntax transformer with an error, it would lead to
degenerate performance (Racket would run out of memory or it would
need to be killed.

Please see this example and uncomment the last non-paren line to see
it fall down:

http://pasterack.org/pastes/50261

The problem is that the `remap-entry` syntax class can succeed in multiple ways because of the repeated pattern. So when you have a macro use like

  (m remap-entry-1 remap-entry-2 ... remap-entry-n bad)

when parsing `bad` fails, syntax-parse backtracks and tries the other way of parsing all of the previous entries, so what should be a linear parse turns exponential.

The easiest fix is to add the #:commit option to the `remap-entry` syntax class. Then when `remap-entry` succeeds the first time, it throws away the choice points it created, so the repeated pattern is never considered.

It's usually reasonable to use #:commit with regular syntax classes (unless you're using syntax-parse to do logic programming). It's usually a bad idea to use it with splicing syntax classes, though, since it can lead to missed parses or bad error messages.

Two other comments:

1. A term like `(a <- blend)` will match the first pattern and treat `blend` as a `remap:id`. If you don't want that to happen, there are two ways to prevent it. One is to define a syntax class like `id` that excludes all of the reserved words like `<-` and `blend` and use that for pattern variables like `remap`. The other is to reorder the patterns and use cut (~!):

(pattern (source:id <- blend ~! remap:id extras:remap-entry-extra-params))
  (pattern (source:id <- remap:id extras:remap-entry-extra-params))

2. `format-id` is useful for creating identifiers.

Ryan

--
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