Module:   dfmc-reader
Synopsis: The state transitions of the Dylan lexer.
Author:   CMU, adapted by Keith Playford
Copyright:    Original Code is Copyright (c) 1995-2004 Functional Objects, Inc.
              All rights reserved.
License:      See License.txt in this distribution for details.
Warranty:     Distributed WITHOUT WARRANTY OF ANY KIND

// Derived from CMU code.
//
// Copyright (c) 1994  Carnegie Mellon University
// All rights reserved.

// $Initial-State -- internal.
//
// Build the state graph and save the initial state.
//

define constant $ascii-8-bit-extensions
  = as(<string>, vector(as(<character>, 128), '-', as(<character>, 255)));

define constant $Initial-State :: <state>
  = compile-state-machine
      (state(#"start", #f,
             pair(" \t\f\r", #"whitespace"),
             pair('\n', #"newline"),
             pair('/', #"slash"),
             pair('#', #"sharp"),
             pair('(', #"lparen"),
             pair(')', #"rparen"),
             pair(',', #"comma"),
             pair('.', #"dot"),
             pair(';', #"semicolon"),
             pair('[', #"lbracket"),
             pair(']', #"rbracket"),
             pair('{', #"lbrace"),
             pair('}', #"rbrace"),
             pair(':', #"colon"),
             pair('-', #"minus"),
             pair('=', #"equal"),
             pair('?', #"question"),
             pair('\\', #"backslash"),
             pair('+', #"plus"),
             pair('~', #"tilde"),
             pair("*^&|", #"operator-graphic"),
             pair("<>", #"operator-graphic-pre-equal"),
             pair("!%@", #"leading-graphic"),
             // pair("!%@_", #"leading-graphic"),
             pair("$", #"leading-dollar"),
             pair("_", #"leading-underscore"),
             pair("A-Za-z", #"symbol"),
             pair('\'', #"quote"),
             pair('"', #"double-quote"),
             pair("0-9", #"decimal")),
       state(#"whitespace", #"whitespace",
             pair(" \t\f\r", #"whitespace")),
       state(#"newline", #"newline"),
       state(#"slash", make-binary-operator,
             pair('/', #"double-slash"),
             pair('*', #"slash-star")),
       state(#"double-slash", #"end-of-line-comment"),
       state(#"slash-star", #"multi-line-comment"),
       state(#"sharp", #f,
             pair('(', #"sharp-paren"),
             pair('[', #"sharp-bracket"),
             pair('{', #"sharp-brace"),
             pair("#", #"sharp-sharp"),
             pair('"', #"sharp-quote"),
             pair("bB", #"sharp-b"),
             pair("oO", #"sharp-o"),
             pair("xX", #"sharp-x"),
             pair("ac-np-wyzAC-NP-WYZ0-9!&*<=>|^$%@_+~?/", #"sharp-name"),
             pair('-', #"sharp-name")
             /*
             pair("tT", #"true"),
             pair("fF", #"false"),
             pair("nN", #"sharp-n"),
             pair("rR", #"sharp-r"),
             pair("kK", #"sharp-k"),
             pair("aA", #"sharp-a"),
             */
             /* CMU
             , pair("eE", #"sharp-e"),
             pair("iI", #"sharp-i")
             */
            ),
       state(#"sharp-paren", fragment-builder(<hash-lparen-fragment>)),
       state(#"sharp-bracket", fragment-builder(<hash-lbracket-fragment>)),
       state(#"sharp-brace", fragment-builder(<hash-lbrace-fragment>)),
       state(#"sharp-sharp", fragment-builder(<hash-hash-fragment>)),

       state(#"sharp-name", make-hash-word,
             pair("a-zA-Z0-9!&*<=>|^$%@_+~?/", #"sharp-name"),
             pair('-', #"sharp-name"),
             pair(':', #"sharp-name-colon")),
       state(#"sharp-name-colon", make-hash-literal),

       state(#"true", fragment-builder(<true-fragment>)),
       state(#"false", fragment-builder(<false-fragment>)),
       state(#"sharp-n", #f, pair("eE", #"sharp-ne")),
       state(#"sharp-ne", #f, pair("xX", #"sharp-nex")),
       state(#"sharp-nex", #f, pair("tT", #"sharp-next")),
       state(#"sharp-next", fragment-builder(<hash-next-fragment>)),
       state(#"sharp-r", #f, pair("eE", #"sharp-re")),
       state(#"sharp-re", #f, pair("sS", #"sharp-res")),
       state(#"sharp-res", #f, pair("tT", #"sharp-rest")),
       state(#"sharp-rest", fragment-builder(<hash-rest-fragment>)),
       state(#"sharp-k", #f, pair("eE", #"sharp-ke")),
       state(#"sharp-ke", #f, pair("yY", #"sharp-key")),
       state(#"sharp-key", fragment-builder(<hash-key-fragment>)),
       state(#"sharp-a", #f, pair("lL", #"sharp-al")),
       state(#"sharp-al", #f, pair("lL", #"sharp-all")),
       state(#"sharp-all", #f, pair('-', #"sharp-all-")),
       state(#"sharp-all-", #f, pair("kK", #"sharp-all-k")),
       state(#"sharp-all-k", #f, pair("eE", #"sharp-all-ke")),
       state(#"sharp-all-ke", #f, pair("yY", #"sharp-all-key")),
       state(#"sharp-all-key", #f, pair("sS", #"sharp-all-keys")),
       state(#"sharp-all-keys", fragment-builder(<hash-all-keys-fragment>)),
       state(#"sharp-quote", #f,
             pair('"', #"quoted-keyword"),
             pair('\\', #"sharp-quote-escape"),
             pair(" !#-[]-~", #"sharp-quote"),
             pair($ascii-8-bit-extensions, #"sharp-quote")),
       state(#"sharp-quote-escape", #f,
             pair("\\abefnrt0\"", #"sharp-quote"),
             pair('<', #"sharp-quote-escape-less")),
       state(#"sharp-quote-escape-less", #f,
             pair("0-9a-fA-F", #"sharp-quote-hex-char-digits")),
       state(#"sharp-quote-hex-char-digits", #f,
             pair("0-9a-fA-F", #"sharp-quote-hex-char-digits"),
             pair('>', #"sharp-quote")),
       state(#"quoted-keyword", make-quoted-symbol),

       state(#"sharp-b", #f,
             pair("01", #"binary-integer"),
             pair('-', #"sharp-name"),
             pair(':', #"sharp-name-colon"),
             pair("a-zA-Z2-9!&*<=>|^$%@_+~?/", #"sharp-name")),
       state(#"binary-integer", parse-integer-literal,
             pair("01", #"binary-integer"),
             pair('-', #"sharp-name"),
             pair(':', #"sharp-name-colon"),
             pair("a-zA-Z2-9!&*<=>|^$%@_+~?/", #"sharp-name")),

       state(#"sharp-o", #f,
             pair("0-7", #"octal-integer"),
             pair('-', #"sharp-name"),
             pair(':', #"sharp-name-colon"),
             pair("a-zA-Z8-9!&*<=>|^$%@_+~?/", #"sharp-name")),
       state(#"octal-integer", parse-integer-literal,
             pair("0-7", #"octal-integer"),
             pair('-', #"sharp-name"),
             pair(':', #"sharp-name-colon"),
             pair("a-zA-Z8-9!&*<=>|^$%@_+~?/", #"sharp-name")),

       state(#"sharp-x", #f,
             pair("0-9a-fA-F", #"hex-integer"),
             pair('-', #"sharp-name"),
             pair(':', #"sharp-name-colon"),
             pair("g-zG-Z!&*<=>|^$%@_+~?/", #"sharp-name")),
       state(#"hex-integer", parse-integer-literal,
             pair("0-9a-fA-F", #"hex-integer"),
             pair('-', #"sharp-name"),
             pair(':', #"sharp-name-colon"),
             pair("g-zG-Z!&*<=>|^$%@_+~?/", #"sharp-name")),

       /* CMU
       state(#"sharp-i", #f, pair("fF", #"sharp-if")),
       state(#"sharp-if", fragment-builder(<hash-if-fragment>)),
       state(#"sharp-e", #f,
             pair('-', #"sharp-e-minus"),
             pair("0-9", #"extended-integer"),
             pair("bB", #"sharp-b"),
             pair("oO", #"sharp-o"),
             pair("xX", #"sharp-x"),
             pair("lL", #"sharp-el"),
             pair("nN", #"sharp-en")),
       state(#"sharp-e-minus", #f,
             pair("0-9", #"extended-integer")),
       state(#"sharp-el", #f, pair("sS", #"sharp-els")),
       state(#"sharp-els", #f, pair("eE", #"sharp-else")),
       state(#"sharp-else", fragment-builder(<hash-else-fragment>),
             pair("iI", #"sharp-elsei")),
       state(#"sharp-elsei", #f, pair("fF", #"sharp-elseif")),
       state(#"sharp-elseif", fragment-builder(<hash-elseif-fragment>)),
       state(#"sharp-en", #f, pair("dD", #"sharp-end")),
       state(#"sharp-end", #f, pair("iI", #"sharp-endi")),
       state(#"sharp-endi", #f, pair("fF", #"sharp-endif")),
       state(#"sharp-endif", fragment-builder(<hash-endif-fragment>)),
       state(#"extended-integer", parse-integer-literal,
             pair("0-9", #"extended-integer")),
       */
       state(#"lparen", fragment-builder(<lparen-fragment>)),
       state(#"rparen", fragment-builder(<rparen-fragment>)),
       state(#"comma", fragment-builder(<comma-fragment>)),
       state(#"dot", fragment-builder(<dot-fragment>),
             pair('.', #"dot-dot"),
             pair("0123456789", #"fp-frac")),
       state(#"dot-dot", #f, pair('.', #"ellipsis")),
       state(#"ellipsis", fragment-builder(<ellipsis-fragment>)),
       state(#"semicolon", fragment-builder(<semicolon-fragment>)),
       state(#"colon", #f,
             pair('=', #"colon-equal"),
             pair(':', #"double-colon"),
             pair("a-zA-Z", #"cname"),
             pair("0-9", #"cname-leading-numeric"),
             pair("!$%@_", #"cname-leading-graphic"),
             pair("+/", #"cname-binop"),
             pair('-', #"cname-binop"),
             pair("*^&|", #"cname-graphic-binop"),
             pair('~', #"cname-tilde"),
             pair("<>", #"cname-angle")),
       state(#"colon-equal", make-binary-operator,
             pair('=', #"cname-binop")),
       state(#"double-colon", fragment-builder(<colon-colon-fragment>),
             pair('=', #"cname-binop")),
       state(#"lbracket", fragment-builder(<lbracket-fragment>)),
       state(#"rbracket", fragment-builder(<rbracket-fragment>)),
       state(#"lbrace", fragment-builder(<lbrace-fragment>)),
       state(#"rbrace", fragment-builder(<rbrace-fragment>)),
       state(#"minus", make-minus,
             pair("0-9", #"signed-decimal")),
       state(#"equal", make-equal,
             pair('=', #"double-equal"),
             pair('>', #"arrow"),
             pair("a-zA-Z", #"symbol"),
             pair("0-9!&*<|^$%@_-+~?/", #"leading-graphic")),
       state(#"double-equal", make-double-equal,
             pair("a-zA-Z", #"symbol"),
             pair("0-9!&*<=>|^$%@_-+~?/", #"leading-graphic")),
       state(#"arrow", fragment-builder(<equal-greater-fragment>),
             pair("a-zA-Z", #"symbol"),
             pair("0-9!&*<=>|^$%@_-+~?/", #"leading-graphic")),
       state(#"question", fragment-builder(<query-fragment>),
             pair('?', #"double-question"),
             pair('=', #"question-equal"),
             pair('@', #"question-at")),
       state(#"double-question", fragment-builder(<query-query-fragment>)),
       state(#"question-equal", fragment-builder(<query-equal-fragment>)),
       state(#"question-at", fragment-builder(<query-at-fragment>)),
       state(#"backslash", #f,
             pair("-+/", #"backslash-done"),
             pair('~', #"backslash-tilde"),
             pair(':', #"backslash-colon"),
             pair('#', #"backslash-sharp"),
             pair("a-zA-Z", #"backslash-symbol"),
             pair("0-9", #"backslash-digit"),
             // TODO: Remove these hacks for parsing machine words.
             // pair("!$%@_", #"backslash-graphic"),
             pair('%', #"backslash-percent"),
             pair("!$@_", #"backslash-graphic"),
             pair("&*^|", #"backslash-graphic-done"),
             pair("=<>", #"backslash-graphic-pre-equal"),
             // EXTENSION: The escaped punctuation extensions used in macros.
             pair('.', #"backslash-dot"),
             pair('?', #"backslash-question")),
       state(#"backslash-dot", fragment-builder(<dot-fragment>),
             pair('.', #"backslash-dot-dot")),
       state(#"backslash-dot-dot", #f,
             pair('.', #"backslash-ellipsis")),
       state(#"backslash-ellipsis", make-escaped-ellipsis),
       state(#"backslash-question", make-escaped-query,
             pair("?", #"backslash-double-question"),
             pair("=", #"backslash-question-equal")),
       state(#"backslash-sharp", #f,
             pair("nN", #"backslash-sharp-n"),
             pair("rR", #"backslash-sharp-r"),
             pair("kK", #"backslash-sharp-k"),
             pair("aA", #"backslash-sharp-a")),
       state(#"backslash-sharp-n", #f, pair("eE", #"backslash-sharp-ne")),
       state(#"backslash-sharp-ne", #f, pair("xX", #"backslash-sharp-nex")),
       state(#"backslash-sharp-nex", #f, pair("tT", #"backslash-sharp-next")),
       state(#"backslash-sharp-next", make-escaped-hash-next-fragment),
       state(#"backslash-sharp-r", #f, pair("eE", #"backslash-sharp-re")),
       state(#"backslash-sharp-re", #f, pair("sS", #"backslash-sharp-res")),
       state(#"backslash-sharp-res", #f, pair("tT", #"backslash-sharp-rest")),
       state(#"backslash-sharp-rest", make-escaped-hash-rest-fragment),
       state(#"backslash-sharp-k", #f, pair("eE", #"backslash-sharp-ke")),
       state(#"backslash-sharp-ke", #f, pair("yY", #"backslash-sharp-key")),
       state(#"backslash-sharp-key", make-escaped-hash-key-fragment),
       state(#"backslash-sharp-a", #f, pair("lL", #"backslash-sharp-al")),
       state(#"backslash-sharp-al", #f, pair("lL", #"backslash-sharp-all")),
       state(#"backslash-sharp-all", #f, pair('-', #"backslash-sharp-all-")),
       state(#"backslash-sharp-all-", #f, pair("kK", #"backslash-sharp-all-k")),
       state(#"backslash-sharp-all-k", #f, pair("eE", #"backslash-sharp-all-ke")),
       state(#"backslash-sharp-all-ke", #f, pair("yY", #"backslash-sharp-all-key")),
       state(#"backslash-sharp-all-key", #f, pair("sS", #"backslash-sharp-all-keys")),
       state(#"backslash-sharp-all-keys", make-escaped-hash-all-keys-fragment),
       state(#"backslash-double-question", make-escaped-query-query),
       state(#"backslash-question-equal", make-escaped-query-equal),
       state(#"backslash-percent", #f,
             pair("-+*/", #"backslash-done"),
             pair("a-zA-Z", #"backslash-symbol"),
             pair("0-9!&<=>|^$%@_~?", #"backslash-graphic")),
       state(#"backslash-done", make-quoted-name),
       state(#"backslash-tilde", make-quoted-name,
             pair('=', #"backslash-tilde-equal")),
       state(#"backslash-tilde-equal", make-quoted-name,
             pair('=', #"backslash-done")),
       state(#"backslash-colon", #f,
             pair('=', #"backslash-done"),
             pair(':', #"backslash-colon-colon")),
       state(#"backslash-colon-colon", make-escaped-colon-colon),
       state(#"backslash-graphic", #f,
             pair("-0-9!&*<=>|^$%@_+~?/", #"backslash-graphic"),
             pair("a-zA-Z", #"backslash-symbol")),
       state(#"backslash-graphic-done", make-quoted-name,
             pair("-0-9!&*<=>|^$%@_+~?/", #"backslash-graphic"),
             pair("a-zA-Z", #"backslash-symbol")),
       state(#"backslash-graphic-pre-equal", make-quoted-name,
             pair('=', #"backslash-graphic-done"),
             pair("-0-9!&*<>|^$%@_+~?/",#"backslash-graphic"),
             pair("a-zA-Z", #"backslash-symbol")),
       state(#"backslash-symbol", make-quoted-name,
             pair("-+~?/!&*<=>|^$%@_0-9a-zA-Z", #"backslash-symbol")),
       state(#"backslash-digit", #f,
             pair("-0-9!&*<=>|^$%@_+~?/", #"backslash-digit"),
             pair("a-zA-Z", #"backslash-digit-alpha")),
       state(#"backslash-digit-alpha", #f,
             pair("-0-9!&*<=>|^$%@_+~?/", #"backslash-digit"),
             pair("a-zA-Z", #"backslash-symbol")),
       state(#"plus", make-binary-operator,
             pair("0-9", #"signed-decimal")),
       state(#"tilde", make-tilde,
             pair('=', #"tilde-equal")),
       state(#"tilde-equal", make-binary-operator,
             pair('=', #"tilde-equal-equal")),
       state(#"tilde-equal-equal", make-binary-operator),
       state(#"operator-graphic", make-binary-operator,
             pair("a-zA-Z", #"symbol"),
             pair("0-9!&*<=>|^$%@_-+~?/", #"leading-graphic")),
       state(#"operator-graphic-pre-equal", make-binary-operator,
             pair('=', #"operator-graphic"),
             pair("a-zA-Z", #"symbol"),
             pair("0-9!&*<>|^$%@_-+~?/", #"leading-graphic")),
       state(#"leading-graphic", #f,
             pair("0-9!&*<=>|^$%@_+~?/", #"leading-graphic"),
             pair('-', #"leading-graphic"),
             pair("a-zA-Z", #"symbol")),
       state(#"leading-dollar", #f,
             pair("0-9", #"history-or-leading-graphic"),
             pair("!&*<=>|^$%@_+~?/", #"leading-graphic"),
             pair('-', #"leading-graphic"),
             pair("a-zA-Z", #"symbol")),
       state(#"history-or-leading-graphic", make-history-name,
             pair("0-9", #"history-or-leading-graphic"),
             pair("!&*<=>|^$%@_+~?/", #"leading-graphic"),
             pair('-', #"leading-graphic"),
             pair("a-zA-Z", #"symbol")),
       state(#"leading-underscore", make-identifier,
             pair("0-9!&*<=>|^$%@_+~?/", #"leading-graphic"),
             pair('-', #"leading-graphic"),
             pair("a-zA-Z", #"symbol")),
       state(#"symbol", make-identifier,
             pair("a-zA-Z0-9!&*<=>|^$%@_+~?/", #"symbol"),
             pair('-', #"symbol"),
             pair(':', #"colon-keyword")),

       state(#"colon-keyword", make-keyword-symbol,
             pair("a-zA-Z", #"cname"),
             pair("0-9", #"cname-leading-numeric"),
             pair("!$%@_", #"cname-leading-graphic"),
             pair("+/", #"cname-binop"),
             pair('-', #"cname-binop"),
             pair("*^&|", #"cname-graphic-binop"),
             pair('~', #"cname-tilde"),
             pair("<>", #"cname-angle"),
             pair('=', #"cname-equal"),
             pair(':', #"cname-colon")),

       state(#"cname-binop", make-constrained-name,
             pair(':', #"colon-qname")),
       state(#"cname-graphic-binop", make-constrained-name,
             pair(':', #"colon-qname"),
             pair("0-9!&*<>|^$%@_+~?/=", #"cname-leading-graphic"),
             pair('-', #"cname-leading-graphic"),
             pair("a-zA-Z", #"cname")),
       state(#"cname-tilde", #f,
             pair('=', #"cname-tilde-equal")),
       state(#"cname-tilde-equal", make-constrained-name,
             pair(':', #"colon-qname"),
             pair('=', #"cname-tilde-double-equal")),
       state(#"cname-tilde-double-equal", make-constrained-name,
             pair(':', #"colon-qname")),
       state(#"cname-angle", make-constrained-name,
             pair(':', #"colon-qname"),
             pair('=', #"cname-angle-equal"),
             pair("0-9!&*<>|^$%@_+~?/", #"cname-leading-graphic"),
             pair('-', #"cname-leading-graphic"),
             pair("a-zA-Z", #"cname")),
       state(#"cname-angle-equal", make-constrained-name,
             pair(':', #"colon-qname"),
             pair("0-9!&*<>|^$%@_+~?/=", #"cname-leading-graphic"),
             pair('-', #"cname-leading-graphic"),
             pair("a-zA-Z", #"cname")),
       state(#"cname-equal", make-constrained-name,
             pair(':', #"colon-qname"),
             pair('=', #"cname-binop")),
       state(#"cname-colon", #f,
             pair('=', #"cname-binop")),
       state(#"cname-leading-numeric", #f,
             pair("0-9!&*<>|^$%@_+~?/=", #"cname-leading-numeric"),
             pair('-', #"cname-leading-numeric"),
             pair("a-zA-Z", #"cname-numeric-alpha")),
       state(#"cname-numeric-alpha", #f,
             pair("0-9!&*<>|^$%@_+~?/=",
                  #"cname-leading-numeric"),
             pair('-', #"cname-leading-numeric"),
             pair("a-zA-Z", #"cname")),
       state(#"cname-leading-graphic", #f,
             pair("0-9!&*<>|^$%@_+~?/=", #"cname-leading-graphic"),
             pair('-', #"cname-leading-graphic"),
             pair("a-zA-Z", #"cname")),
       state(#"cname", make-constrained-name,
             pair(':', #"colon-qname"),
             pair("a-zA-Z0-9!&*<>|^$%@_+~?/=", #"cname"),
             pair('-', #"cname")),

       state(#"colon-qname", #f,
             pair("a-zA-Z", #"qname"),
             pair("0-9", #"qname-leading-numeric"),
             pair("!$%@_", #"qname-leading-graphic"),
             pair("+/", #"qname-binop"),
             pair('-', #"qname-binop"),
             pair("*^&|", #"qname-graphic-binop"),
             pair('~', #"qname-tilde"),
             pair("<>", #"qname-angle"),
             pair('=', #"qname-equal"),
             pair(':', #"qname-colon")),

       state(#"qname-binop", make-qualified-name),
       state(#"qname-graphic-binop", make-qualified-name,
             pair("0-9!&*<>|^$%@_+~?/=", #"qname-leading-graphic"),
             pair('-', #"qname-leading-graphic"),
             pair("a-zA-Z", #"qname")),
       state(#"qname-tilde", #f,
             pair('=', #"qname-tilde-equal")),
       state(#"qname-tilde-equal", make-qualified-name,
             pair('=', #"qname-tilde-double-equal")),
       state(#"qname-tilde-double-equal", make-qualified-name),
       state(#"qname-angle", make-qualified-name,
             pair('=', #"qname-angle-equal"),
             pair("0-9!&*<>|^$%@_+~?/", #"qname-leading-graphic"),
             pair('-', #"qname-leading-graphic"),
             pair("a-zA-Z", #"qname")),
       state(#"qname-angle-equal", make-qualified-name,
             pair("0-9!&*<>|^$%@_+~?/=", #"qname-leading-graphic"),
             pair('-', #"qname-leading-graphic"),
             pair("a-zA-Z", #"qname")),
       state(#"qname-equal", make-qualified-name,
             pair('=', #"qname-binop")),
       state(#"qname-colon", #f,
             pair('=', #"qname-binop")),
       state(#"qname-leading-numeric", #f,
             pair("0-9!&*<>|^$%@_+~?/=", #"qname-leading-numeric"),
             pair('-', #"qname-leading-numeric"),
             pair("a-zA-Z", #"qname-numeric-alpha")),
       state(#"qname-numeric-alpha", #f,
             pair("0-9!&*<>|^$%@_+~?/=",
                  #"qname-leading-numeric"),
             pair('-', #"qname-leading-numeric"),
             pair("a-zA-Z", #"qname")),
       state(#"qname-leading-graphic", #f,
             pair("0-9!&*<>|^$%@_+~?/=", #"qname-leading-graphic"),
             pair('-', #"qname-leading-graphic"),
             pair("a-zA-Z", #"qname")),
       state(#"qname", make-qualified-name,
             pair("a-zA-Z0-9!&*<>|^$%@_+~?/=", #"qname"),
             pair('-', #"qname")),

       state(#"quote", #f,
             pair(" -&(-[]-~", #"quote-char"),
             pair($ascii-8-bit-extensions, #"quote-char"),
             pair('\\', #"quote-escape")),
       state(#"quote-escape", #f,
             pair("\\'\"abefnrt0", #"quote-char"),
             pair('<', #"quote-escape-less")),
       state(#"quote-escape-less", #f,
             pair("0-9a-fA-F", #"quote-hex-char-digits")),
       state(#"quote-hex-char-digits", #f,
             pair("0-9a-fA-F", #"quote-hex-char-digits"),
             pair('>', #"quote-char")),
       state(#"quote-char", #f,
             pair('\'', #"character")),
       state(#"character", make-character-literal),
       state(#"double-quote", #f,
             pair('"', #"string"),
             pair('\\', #"double-quote-escape"),
             pair(" !#-[]-~", #"double-quote"),
             pair($ascii-8-bit-extensions, #"double-quote")),
       state(#"string", make-string-literal),
       state(#"double-quote-escape", #f,
             pair("\\'\"abefnrt0", #"double-quote"),
             pair('<', #"double-quote-escape-less")),
       state(#"double-quote-escape-less", #f,
             pair("0-9a-fA-F", #"double-quote-hex-char-digits")),
       state(#"double-quote-hex-char-digits", #f,
             pair("0-9a-fA-F", #"double-quote-hex-char-digits"),
             pair('>', #"double-quote")),
       state(#"decimal", parse-integer-literal,
             pair("0-9", #"decimal"),
             pair('/', #"decimal-slash"),
             pair('.', #"fp-frac"),
             pair("eEsSdDxX", #"decimal-e")),
       state(#"decimal-slash", #f,
             pair("0-9", #"ratio"),
             pair("a-zA-Z", #"numeric-alpha"),
             pair("!&*<=>|^$%@_+~?/", #"leading-numeric"),
             pair('-', #"leading-numeric")),
       state(#"numeric-alpha", #f,
             pair("a-zA-Z", #"symbol"),
             pair("0-9!&*<=>|^$%@_+~?/", #"leading-numeric"),
             pair('-', #"leading-numeric")),
       state(#"leading-numeric", #f,
             pair("a-zA-Z", #"numeric-alpha"),
             pair("0-9!&*<=>|^$%@_+~?/", #"leading-numeric"),
             pair('-', #"leading-numeric")),

       state(#"ratio", parse-ratio-literal,
             pair("0-9", #"ratio"),
             pair("a-zA-Z", #"numeric-alpha"),
             pair("-!&*<=>|^$%@_+~?/", #"leading-numeric")),

       state(#"signed-decimal", parse-integer-literal,
             pair("0-9", #"signed-decimal"),
             pair('/', #"signed-decimal-slash"),
             pair('.', #"fp-frac")),
       state(#"signed-decimal-slash", #f,
             pair("0-9", #"signed-ratio")),
       state(#"signed-ratio", parse-ratio-literal,
             pair("0-9", #"signed-ratio")),

       state(#"fp-frac", parse-fp-literal,
             pair("0-9", #"fp-frac"),
             pair("eEsSdDxX", #"fp-e")),
       state(#"fp-e", #f,
             pair('-', #"fp-e-sign"),
             pair('+', #"fp-e-sign"),
             pair("0-9", #"fp-exp")),
       state(#"fp-e-sign", #f,
             pair("0-9", #"fp-exp")),
       state(#"fp-exp", parse-fp-literal,
             pair("0-9", #"fp-exp")),

       state(#"decimal-e", #f,
             pair("a-zA-Z", #"symbol"),
             pair("[0-9]", #"decimal-exp"),
             pair("!&*<=>|^$%@_~?/", #"leading-numeric"),
             pair('-', #"decimal-e-sign"),
             pair('+', #"decimal-e-sign")),
       state(#"decimal-exp", parse-fp-literal,
             pair("0-9", #"decimal-exp"),
             pair("a-zA-Z", #"numeric-alpha"),
             pair("!&*<=>|^$%@_+~?/", #"leading-numeric"),
             pair("-", #"leading-numeric")),
       state(#"decimal-e-sign", #f,
             pair("0-9", #"decimal-exp"),
             pair("a-zA-Z", #"numeric-alpha"),
             pair("!&*<=>|^$%@_+~?/", #"leading-numeric"),
             pair("-", #"leading-numeric")));
