     'group' sp , 
     'repeat0' sp ,
     'optional' sp , 
-   ] choice* repeat1 [ 
+  ] choice* repeat1 [ 
      dup length 1 = [ first ] [ <ebnf-sequence> ] if
-   ] action ;  
+  ] action ;  
 
 : 'choice' ( -- parser )
   'sequence' sp "|" token sp list-of [ 
     dup length 1 = [ first ] [ <ebnf-choice> ] if
-   ] action ;
+  ] action ;
 
 : 'action' ( -- parser )
   [

  #! Parses the string, ignoring white space, and
  #! does not put the result in the AST.
  token sp hide ;

: 'identifier' ( -- parser )
  #! Return a parser that parses an identifer delimited by


DEFER: 'choice'

: grouped ( begin quot end -- parser )
  #! Parse a group of choices, where the delimiter for the
  #! group is specified by 'begin' and 'end'. The quotation
  #! should produce the AST to be the result of the parser.
  [ [ 'choice' sp ] delay swap action ] dip syntax-pack ;

: 'group' ( -- parser )
  "(" [ ] ")" grouped ;

: 'repeat0' ( -- parser )
  "{" [ <ebnf-repeat0> ] "}" grouped ;

: 'optional' ( -- parser )
  "[" [ <ebnf-optional> ] "]" grouped ;

: 'sequence' ( -- parser )
  [ 
