Skip to content

Instantly share code, notes, and snippets.

@denkspuren
Last active August 29, 2015 14:09
Show Gist options
  • Save denkspuren/c71b956efd610aa3fda2 to your computer and use it in GitHub Desktop.
Save denkspuren/c71b956efd610aa3fda2 to your computer and use it in GitHub Desktop.
A simple parser for parentheses implemented with delimited continuations using Consize
% A simple parser for parentheses implemented with delimited continuations
% using Consize, @denkspuren 2014-11-12 (Update)
%
% The implementation demonstrates parsing of brackets with delimited
% continuations. Since parentheses are already used in Consize,
% left and right parentheses are written as `((` and `))`, respectively.
%
% Take a program such as: `(( @A (( @B (( @C )) @D (( @E )) @F )) @G ))`;
% `@A `up to `@G` denote arbitrary code without any parentheses. As soon as
% word `((` is processed, `shift` starts looking for left and right
% parentheses in the code to come. Depending on the sequence of parentheses
% a corresponding stack is constructed. There are four situations reflecting
% two states of processing. On the right, the words to properly built the
% stack are shown. The following definition of `attach` comes in handy.
: attach ( [ @Stk ] #Itm -- [ @Stk #Itm ] ) ( ) cons concat ;
% 1. @X ( @Y (
% 1. @X ( @Y ) attach
% 2. @X ) @Y ( concat
% 2. @X ) @Y ) concat attach
%
% How does the parser know it's finished? We use a marker, word `!`, indicating
% when we are done.
%
% Since of no importance for demonstration purposes, the parser does not
% provide any means to pass words `((` and `))` literally on the stack.
%
% The code requires `\ delco.txt run` prior to executing this file.
: (( \ ! scan-brackets-open (( ;
: final-closing-bracket?
over \ ! equal? [ nip top ] [ scan-brackets-closed ] if ;
: scan-brackets-open
{ \ (( [ scan-brackets-open ]
\ )) [ attach final-closing-bracket? ]
} shift ;
: scan-brackets-closed
{ \ (( [ concat scan-brackets-open ]
\ )) [ concat attach final-closing-bracket? ]
} shift ;
[ [ ] ] [ (( )) ] unit-test
[ [ [ ] ] ] [ (( (( )) )) ] unit-test
[ [ [ [ ] ] ] ] [ (( (( (( )) )) )) ] unit-test
[ [ 1 ] ] [ (( 1 )) ] unit-test
[ [ 1 2 3 ] ] [ (( 1 2 3 )) ] unit-test
[ [ [ 1 ] ] ] [ (( (( 1 )) )) ] unit-test
[ [ 1 [ 2 ] ] ] [ (( 1 (( 2 )) )) ] unit-test
[ [ [ 1 ] 2 ] ] [ (( (( 1 )) 2 )) ] unit-test
[ [ 1 [ 2 ] 3 ] ] [ (( 1 (( 2 )) 3 )) ] unit-test
[ [ 1 [ 2 ] [ 3 ] 4 ] ] [ (( 1 (( 2 )) (( 3 )) 4 )) ] unit-test
[ [ 1 [ 2 ] 3 [ 4 ] 5 ] ] [ (( 1 (( 2 )) 3 (( 4 )) 5 )) ] unit-test
[ [ 1 [ 2 [ [ 3 ] 4 ] ] 5 ] ] [ (( 1 (( 2 (( (( 3 )) 4 )) )) 5 )) ] unit-test
[ [ 3 2 1 ] 4 ] [ (( 1 2 3 )) reverse 4 ] unit-test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment