A simple parser

  1. A simple parser
    1. But my transformations depend on state
    2. But I want to reorder things
    3. Source code

Acetone is a parser for Chicken Scheme that helps you turn lists into trees.

Acetone contains one procedure, parse, that works like a map-in-order:

(parse add1 '(0 1 2))
⇒ (1 2 3)

Except it can also handle multiple values, or zero:

(parse (fn (when (even? x) (values x x))) '(0 1 2 3))
⇒ (0 0 2 2)

It can also insert parentheses by using the keywords #:open and #:close like this:

(parse (fn (cond ((zero? (modulo x 3)) (values #:open x))
                 ((= 2 (modulo x 3)) (values x #:close))
                 (else x)))
       (iota 8))
⇒ ((0 1 2) (3 4 5) (6 7))

So once you have your lists of tokens (you get that from a lexer, which means something like string-split or read-lines), you can use parse with a procedure you write that transforms the tokens and adds structure with #:open and #:close.

This also works which is sometimes useful:

((parse add1) (iota 3))
⇒ (1 2 3)

But my transformations depend on state

No problem, just use side-effects! Keep track of state separately, with parameters, call-tables, or closures.

But I want to reorder things

Moving things down is no problem, just stash them in separate state and grab them back when you need them.

Moving things up requires separate passes. Go through it once, yank out and collect everything you want to move up (in a call-table for example), and then go through it again and put it in where it belongs.

Source code

git clone https://idiomdrottning.org/acetone